Python函数
函数时Python为了代码最大程度的重复使用和最小化代码冗余而提供的基本程序结构。
Python可以创建4类函数:
1、全局函数:定义在模块中
2、局部函数:嵌套在其他函数中
3、lambda函数:匿名函数---表达式。更高的灵活度
4、方法:与特定数据类型关联的函数,并且只能与数据类型关联一起使用。
def functionName(parameters):
suite
def是一个可执行的语句,不能嵌套在其他的非语句中,例如在一个列表解析[]中。但是可以嵌套在其他类似if 、while 语句。def创建了一个对象并将其赋值给一个变量名(函数名)。return语句用于返回对象,返回多个值,彼此间用逗号分隔,表现为一个元组。pass 占位语句。
函数的作用域:
名称空间---一个变量所能生效的范围。模块定义全局作用域(范围仅限于单个文件),而函数定义本地作用域,每次对函数的调用都会创建一个新的本地作用域,赋值的变量除非声明为全局变量,否则均为本地变量。所有的变量名都可以归纳为本地、全局或内置(__builtin__模块提供)。
在函数内部可以使用全局变量。函数内部和全局变量同名的变量,但不会改变全局变量。
global x 声明全局变量。
本地变量在函数返回时消失。
Built-in > Global > Enclosing function locals > local
LEGB原则,首先是本地,之后是函数内,接着是全局,最后是内置。
作用域越小,优先级越高。
In [68]: def f1():
....: x = 3
....: def f2():
....: y = "hello"
....: print x,y
....: return f2
....:
In [69]: f1()
Out[69]: <function __main__.f2>
In [70]: a1 = f1()
In [71]: type(a1)
Out[71]: function
In [72]: a1()
3 hello
当函数嵌套时,我们直接返回了内层函数,如果内层函数调用了外层函数的变量,那么它会自动记忆外层函数变量。所以即使外层函数返回结束,内层函数也可以用外层函数的变量。(函数的闭合--工厂函数--Python的闭包)
def functionName(arg1,arg2,.....)
变量属于不可变对象,函数内部改变对象,并不会真的改变原有对象。函数对可变对象(列表等)的操作可以改变原有对象。
In [81]: l1 = [1,2,3]
In [82]: def f5(x):
....: x.pop()
....: print x
....:
In [83]: f5(l1[:])
[1, 2]
In [84]: print l1
[1, 2, 3]
传递的并非对象本身,而是对象的副本。
参数传递:
参数匹配模型
有多个参数时,按照位置自左向右逐一匹配。
关键字参数
In [85]: m = 3; n = 4
In [86]: def f6(x,y):
....: print x,y
....:
In [88]: f6(m,n)
3 4
In [89]: f6(n,m)
4 3
In [90]: f6(y=n,x=m)
3 4
[91]: def f7(x,y,z):
....: print x,y,z
....:
In [92]: o = 8
In [93]: f7(m,n,o)
3 4 8
In [94]: f7(m,z=o,y=n)
3 4 8
非关键字参数不能放在关键字参数后面。左侧只能是所有的位置参数。
In [95]: f7(z=o,y=n,n)
File "<ipython-input-95-43447ad22aaf>", line 1
f7(z=o,y=n,n)
SyntaxError: non-keyword arg after keyword arg
默认参数,定义函数时使用name = value 的语法直接给变量一个值,从而传入的值可以少于参数个数。
In [96]: def f8(x,y,z=9):
....: print x,y,z
....:
In [97]: f8(m,n,0)
3 4 0
In [98]: f8(m,n,o)
3 4 8
In [99]: f8(m,n)
3 4 9
In [100]: f8(m)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-100-7d2733874ff5> in <module>()
----> 1 f8(m)
TypeError: f8() takes at least 2 arguments (1 given)
定义默认参数只能在无默认值的参数后边。
可变参数:定义函数时,使用*开头的参数,可用于收集任意多基于位置参数。使用** 收集关键字参数。
In [101]: def f10(*x):
.....: print x
.....:
In [102]: f10(m)
(3,)
In [103]: f10(m,n)
(3, 4)
In [104]: f10(m,n,9)
(3, 4, 9)
In [105]: def f11(**x):
.....: print x
.....:
In [106]: f11(x=1,y=2,z=9)
{'y': 2, 'x': 1, 'z': 9}
In [107]: def f12(x,*y):
.....: print x,y
.....:
In [108]: f12(m,n,o)
3 (4, 8)
In [109]: def f13(x,y=10,*z):
.....: print x
.....: print y
.....: print z
.....:
In [110]: f13(m,n,o)
3
4
(8,)
In [111]: def f15(*x,**y):
.....: print x
.....: print y
.....:
In [112]: f15(m,n,o,i=8,j=6)
(3, 4, 8)
{'i': 8, 'j': 6}
可变参数解包:调用时,使用*开头的参数,用于将参数集合打散,从而传递任意多基于位置或关键字的参数。--参数分解
分解赋值:
In [113]: l1 = ['Sun','Mon','Tus']
In [114]: x,y,z = l1
In [115]: print x,y,z
Sun Mon Tus
In [116]: print x
Sun
分解参数:
In [117]: def f17(x,y,z):
.....: print x,y,z
.....:
In [118]: f17(*l1)
Sun Mon Tus
In [119]: l2 = ['a','b','c','d']
In [120]: f17(*l2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-120-11c8d83d4d4d> in <module>()
----> 1 f17(*l2)
TypeError: f17() takes exactly 3 arguments (4 given)
必须匹配个数。
In [121]: l3 = ['a','b']
In [122]: f17(m,*l3)
3 a b
In [123]: def f18(x,*y):
.....: print x
.....: print y
.....:
In [124]: f18(m,*l3)
3
('a', 'b')
d1 = {'key1':'v1','key2':'v2','key3':2}
In [127]: def f19(x,*y,**z):
print x
print y
.....: print z
.....:
In [128]: f19(m,*l3,**d1)
3
('a', 'b')
{'key3': 2, 'key2': 'v2', 'key1': 'v1'}
In [129]: f19(m,n,o,**d1)
3
(4, 8)
{'key3': 2, 'key2': 'v2', 'key1': 'v1'}
lambda--匿名函数:
lambda args:expression
In [139]: lambda x,y: x + y
Out[139]: <function __main__.<lambda>>
In [139]: lambda x,y: x + y
Out[139]: <function __main__.<lambda>>
In [140]: f20 = lambda x,y : x+ y
In [141]: f20(1,2)
Out[141]: 3
函数本身没有名称,通过赋值给一个变量来进行调用。
lambda语句定义的代码必须是合法的表达式,不能出现多条件语句(可使用if的三元表达式)和其他非表达式语句,如for和while等
lambda的首要目的是指定短小的回调函数,lambda将返回一个函数而不是将函数赋值给某变量名。
lambda也支持使用默认参数。
In [144]: f2 = lambda x,y,z=10 : x+y+z
In [145]: f2(1,2)
Out[145]: 13
In [147]: l1 = [ (lambda x : x*2),(lambda y :y*3) ]
In [150]: for i in l1:
print i(4)
.....:
8
12
浙公网安备 33010602011771号