函数就是将一些语句集合在一起的部件,他们能够不止一次的程序中运行,函数还能够计算出一个返回值,并能够改变作为函数输入的参数。而这些参数在代码运行时每次都不同。以函数的形式去编写一个操作可以使它成为一个广泛的应用工具。
基本格式:
def 函数名: 函数体 return 返回值
定义和调用
定义函数按照前面的基本格式定义函数,调用函数时要使用函数名加括号来调用函数,括号中可以包含一个或多个参数。这些参数将会传递给函数头部的参数名。
#定义 def test(x,y): return x*y #调用 test(5,10)
函数参数
必备参数
func(valule) 函数调用时会通过位置来匹配,调用函数时参数不能省略。
默认参数(关键字参数)
func(name=value) 函数如果在调用的时候不给参数,就按默认参数的值进行传递,如果在调用函数时给默认参数重新赋值则原值会被覆盖,
def func(name="Joe"): print(name) func() >>>Joe func("AustinJoe") #func(name="AustinJoe")也是可以的 >>>AustinJoe
不定长参数
- func(*args) 将所有位置相关的参数收集到一个新的元组之中,并将这个元组值赋值给变量args。*可以匹配任意长度和数目的参数。
def func(*args): print(args) func(*(1,2,3,4))#func(1,2,3,4)这种形式也是可以的 >>>(1, 2, 3, 4) func([1,2,3],'hello','python') >>>([1, 2, 3], 'hello', 'python')
2.func(**kwargs)与上面类似,但是是将参数收集到字典中。
def func(**kwargs): print(kwargs) func(a=1,b=2) >>>{'b': 2, 'a': 1}
func(**{'a':1,'b':2})
>>>{'a': 1, 'b': 2}
解包参数
在python中我们可以用*和**对参数解包。
def func(a,b,c,d): print(a,b,c,d) args=(1,2,3,4) func(*args) >>>1 2 3 4
def func(a,b,c,d): print(a,b,c,d) args={'o':1,'b':2,'c':3,'d':4} func(**args) >>>1 2 3 4
注意
参数类型是可以混合使用的,但必须遵循以下法则:
- 在函数调用中,参数必须以此顺序出现:位置参数,后面跟着任何关键字参数,然后是*args,最后跟着**kwargs。
- 在函数头部,参数必须以此顺序出现:一般参数后面紧跟着默认参数,如果有的话后面是*args,最后是**kwargs。
匿名函数:lambda
lambda是一个表达式,表达式创建了一个之后能够调用的函数,但是他返回了一个函数而不是将这个函数赋值给变量名。
其一般格式为:
lambda:argument1,argument2··· argumentN :expression using arguments
f = lambda x, y, z: x + y + z print(f(2, 3, 4)) >>>9
lambda表达式常常与map()和filter()函数结合使用,我们接下来就学习这两个函数。
map():在序列中映射
map函数会对一个序列对象中的每个元素应用被传入的函数,并且返回了包含所用函数调用结果的一个列表。
l=list(map((lambda x:x+2),[1,2,3,4])) print(l)
>>>[3, 4, 5, 6]
l=list(map(pow,[1,2,3],[5,6,7])) print(l) >>>[1, 64, 2187]
filter():过滤元素
filter()函数会根据测试函数过滤出一些元素。
l=list(filter((lambda x:x>0),range(-10,10))) print(l) >>>[1, 2, 3, 4, 5, 6, 7, 8, 9]
reduce()
reduce()函y数会对每一个元素应用函数并运行到最后结果。
from functools import reduce result=reduce((lambda x,y:x+y),[1,2,3,4]) print(result) >>>10
闭包:函数嵌套(间接函数调用)
闭包是指函数外面调用函数里面的的函数,即函数嵌套。
def main(): print("hello world") def nest(): print("我是嵌套的函数!") return nest # 第一种形式 main()() >>>hello world >>>我是嵌套的函数! # 第二种形式 m=main() m() >>>hello world >>>我是嵌套的函数!
递归函数
递归函数的使用要注意:
- 递归的次数在python中是有限制的;
- 递归函数使用时占用的内存成几何量增长;
- 递归函数要有终止条件。
# 对一个列表求和 def sumtree(L): tot = 0 for x in L: if not isinstance(x, list): tot += x else: tot += sumtree(x) return tot L = [1, [1, 2, [6, 7], 3], 4, 5, [9, 8]] print(sumtree(L)) >>>46
回调函数
函数A的执行取决于函数B中某一条件的执行,则函数A为回调函数。
def main(x): if x>5: print("回调函数未执行!!") else: return callback() def callback(): print("回调函数执行!!") main(10) >>>回调函数未执行!! main(4) >>>回调函数执行!!
作用域
作用域法则:
- 内嵌的模块是全局作用域;
- 全局作用域的范围仅限于单个文件;
- 每次对函数的调用都创建了一个本地作用域;
- 赋值的变量名除非声明为全局变量和非本地变量,否则均为本地变量;
- 所有其他的变量名都可以归纳为本地,全局或者内置的。
X=88 def func(Y): Z=X+Y return Z print(func(12)) # 其中X和函数func都是全局变量名,而Y和Z均为本地变量名
global语句
global 语句用来声明一个全局或多个全局变量名。
X = 88 def func(): global X X = 99 func() print(X) >> > 99
nonlocal语句
在声明nonlocal变量名时,该变量名必须存在函数的嵌套的作用域,即他们只能存在于一个嵌套的函数中,并且不能有一个嵌套的def中的第一次赋值创建。
def tester(start): state = start def nested(label): nonlocal state print(label, state) state += 1 return nested f = tester(0) print(f('first')) >>>first 0 print(f('second')) >>>second 1 print(f('third')) >>>third 2