python基础-函数

来源:互联网 发布:relex软件 破解版 编辑:程序博客网 时间:2024/06/06 09:19

函数

函数的作用是将一坨代码组合到一起实现一个功能,并且可以复用,以简化代码,节省人力。

def functionName(param):    process

函数的定义格式如上

def greet():    print('welcome to python')greet()

函数的调用采用的方式是函数名称+(),函数名存放的是对函数对象的引用,所以我们也可以赋值给其它变量.
如:

def greet():    print('welcome to python')g = greetg()

上述代码将greet赋值给g,g()也会打印相同的结果

def greet():    print('welcome to python')def hello():    print('hwllo,python')def world():    print('world,python')list = [greet,hello,world]for x in list:    x();输出:welcome to pythonhwllo,pythonworld,python

很显然,我们可以将函数名称组成一个列表,然后遍历调用

def sum(x,y,z=1):    return x+y+znum = sum(1,2)print(num)输出:4

上述我们把z的值默认等于了1,因此sum()函数只需传两个参数即可。

def sum(x=1,y,z):    return x+y+znum = sum(1,2)print(num)输出:    def sum(x=1,y,z):           ^SyntaxError: non-default argument follows default argument

python不允许不带默认参数的参数跟随一个带有默认参数的参数的后面。可以想象,如果sum(1,2)的话,1的值是给x还是给y呢?

def frange(arg0,arg1=None,arg2=None):    '''类似于range()的浮点数生成器'''    start = 0.0    inc = 1.0    if arg2 is not None: #3个参数均有        start = arg0        stop = arg1        inc = arg2    elif arg1 is not None:#给定2个参数        start = arg0        stop = arg1    else:                 #给定1个参数        stop = arg0    result = []    while start <(stop-(inc/2.0)):        result.append(start)        start+=inc    return resultres = frange(3.0,5,1.0)print(res)#res [3.0, 4.0]

上述的代码是默认参数应用的例子,如果给定3个参数,第一个为开始,第二个为结束,第三个为步长。
”’文档”’ ,三个单引号或者三个双引号之间的为文档注释,它存在的意义是给定一个简单的总结说明。
可以看到,比较的时候用的is not None,而不是 !=None,在python中None的实例只有一个,因此,所有None的id(None)值都是一样的,is 比较的是地址,而!=None比较的是值,比较地址相对于从地址中取值再比较的速度是有优势的。
参数传递的都是对象的引用,但是因为字符串和整数的变量是不可变的,一个不可变参数的值在函数内发生了改变,该参数就会绑定到一个新的对象上,而它原先引用的对象则不会发生改变。
返回值和java不同的是,无需给定指定的类型,可以显式的return。非显式的就会返回None.

生成器函数

def frange(arg0,arg1=None,arg2=None):    '''类似于range()的浮点数生成器'''    start = 0.0    inc = 1.0    if arg2 is not None: #给定3个参数                start = arg0        stop = arg1        inc = arg2    elif arg1 is not None:#给定2个参数        start = arg0        stop = arg1    else:                 #给定1个参数        stop = arg0    result = []    while start <(stop-(inc/2.0)):        yield start        start+=incres = frange(3.0,5.0,1.0)print(res)for x in res:    print(x)输出:<generator object frange at 0x02BA7F80>3.04.0

把return换成yield,就可以把函数转换成一个生成器。对于长列表,使用生成器的这种形式会更效率些,因为使用列表的那种形式会在内存中创建整个列表,而生成器每次只创建一个元素。yield和return语句比较相似,有个不同的是yield会接着上次的状态继续执行,如yield第一次返回是3.0,第二次返回的是4.0,那么3.0的状态依然存在。于是这个生产器包含的值是3.0和4.0.

res = frange(3.0,5.0,1.0)print(res)print(next(res))print(next(res))print(next(res))输出:

res生成器中有3.0 4.0 ,当输出4.0后再次next(),就会报StopIteration异常。

res = frange(3.0,5.0,1.0)for x in res:    print(x)res = frange(3.0,5.0,1.0)resl = list(res)print(resl)输出:[3.0, 4.0][3.0, 4.0]

可以看到,列表的构造函数和for循环可以自动处理StopIteration异常

关键字参数的使用

def simplify(text, space=" \t\r\n\f", delete=""):    result = []    word = ""    for char in text:  # 遍历text        if char in delete:  # 判断字符是否在delete中 如果在则跳出本层循环            continue        elif char in space:  # 判断是否在space            if word:  # 如果word存在                result.append(word)  # 将word添加到列表                word = ""        else:            word += char  # 即不在delete,也不在space,拼接到word    if word:        result.append(word)    return " ".join(result)print(simplify(' this   and\n that\t too')) #this and that too)print(simplify(" Hello. world ",delete="."))#Hello worldprint(simplify(delete="aed",text="sdeja")) #s j

上述代码的含义是去掉给定字符串的空格,或者指定需要删除的字符,在第一个调用中,simplify(’ this and\n that\t too’))我们使用了默认的space和delete参数,第二个调用中我们指定了一个关键字参数delete,使用了space默认参数,第三个调用我们给定两个关键字参数。可以看出,如果使用关键字参数,其参数的顺序由自己决定,但是如果使用了位置参数,那么位置参数的顺序要放在关键字参数的前面,如例二。

lambda函数

function = lambda x:pow(x,3)print(function(2)) #8

lambda用来创建简单的匿名函数,它不能包含分支也不能包含循环,也没有return语句,其返回值仅仅是表达式计算后得到的值。如上述的代码就是计算x的3次方的值。

动态函数的创建

import sysif sys.version_info[:2]<(2,4):    def sorted(items):        items = list(items)        items.sort()        return items

这段代码的含义是当python解释器的版本在2.4以下时,定义一个sorted()函数,因为sorted()函数是在python2.4中加入的。
sys.version_info是一个元组,其保存了当前使用的python解释器的版本,如:sys.version_info(major=3, minor=4, micro=4, releaselevel=’final’, serial=0),我目前使用的版本是3.4.4,[:2]是切片的操作,截取前两个元素与(2,4)比较,这里需要注意的是元组可以进行比较的操作,但前提是元组里面的元素可以比较。看下面这段代码:

print((2,3)<(4,5)) #Trueprint((2,3)<(1,4)) #Falseprint((2,3)<(1,2)) #False

上述的比较类似于 2<3 and 3<5 ,必须都满足条件返回的才是True.

偏函数

#偏函数的应用def hello(who):    print('hello',who)hello('me') #hello me

上述的代码,传进一个参数,并打印,现在我只想向自己问好,也就是说,我们确定了参数的值为me,现在想把函数和参数都封装到一起,组成一个可调用的对象,那么该如何改造呢?

def partial(func,arg):    def callme():        return func(arg)    return callmedef hello(who):    print('hello',who)f1=partial(hello,'me')f1()输出:hello me

partial有两个参数,一个是要调用的函数的引用,一个是要调用函数的参数。在上面的例子中,partial(hello,’me’)返回相当于返回的是hello(‘me’)的hello.传给f1,f1()调用.

import functoolsdef hello(who):    print('hello',who)f1=functools.partial(hello,'me');输出:hello me

这里python为我们提供了一个工具functools,可以直接实现函数和参数绑定的操作

总结:

  1. 我们讲了函数的定义,def f(参数1,参数2,...),f中存储的是函数对象的引用,f()加个括号为调用该函数,我们也可以这样操作g=f;g(),这样也可以调用函数。

  2. 默认参数,def f(参数1,参数2=2),默认参数存在的情况下,调用函数可以只传不带默认参数的值,如f(1),这里需要注意的是,定义带默认值的函数时,带默认值的参数要放在不带默认值参数的后面。

  3. is not None,is not比较的是内存中的地址,==比较的是地址中的值,比较地址比比较值要快一些,因为比较值要先从地址中取值。None对象是全局变量,在python中只存在一个。

  4. 生成器函数, 将函数中的return换成yield就可,生成器的优点在于可以不用一次性生成很多值来占用内存,并且在需要的时候才会生成对应的值。生成器遍历完成再次next()会出现stopIteration异常,欣慰的是for循环和list的构造函数可以自动的处理它。

  5. 关键字参数是将参数名+参数值传给函数,如def f(a,b) 调用的时候这样传参 f(b=2,a=1),关键字参数间可以随意的更改参数的位置,如f(a=1,b=2),但是如果有位置参数的话,关键字参数要放在位置参数的后面。

  6. 匿名函数用关键字lambda来定义,它只能有一些简单的语句,不能包含return ,循环,分支结构。f=lambda x:pow(x,3)

  7. 动态函数的创建:动态函数就是在某些条件满足的条件下,再创建函数

  8. 偏函数:我们想让函数和其参数绑定起来,python提供的工具functools.partial(func,param)可以实现这一要求。

原创粉丝点击