[PY3]——Python的函数
Python函数总结图
1.调用
1.1 如何调用
1.1.1 函数名(传参)
# 函数使用函数名来调用,函数名后紧跟一对小括号,小括号里传入函数定义时要求的参数 add(9,9) #9+9=18
1.2 传参
1.2.1 传参方法1:位置参数
1.2.2 传参方法2:关键字参数
def add(x,y): ret=x+y print('{}+{}={}'.format(x,y,ret)) return ret # 传参方法1:位置参数 指参数按照定义的顺序传入 add(8,9) #8+9=17 # 传参方法2:关键字参数 指参数按照定义时的变量名传入 add(x=9,y=8) #9+8=17 # 规则1:位置参数和关键字参数可以混合使用 add(3,y=9) #3+9=12 # 规则2:但混合使用时,位置参数必须在前面,否则SyntaxError
add(x=3,9) #SyntaxError: positional argument follows keyword argument # 注意1: add('3','9') #3+9=39 # 注意2:传入参数必须和函数定义时的参数相匹配,如果不匹配会抛出TypeError add(9,9,9) #TypeError: add() takes 2 positional arguments but 3 were given
1.3 参数解构
1.3.1 位置参数解构:*可迭代对象
1.3.2 关键字参数解构:*字典
iter=[3,9] add(iter[0],iter[1]) #3+9=12 # 位置参数解构:*可迭代对象 可以把可迭代对象解构成位置参数 add(*iter) #3+9=12 add(*range(2)) #0+1=1 # 关键字参数解构:*字典 可以把字典解构成关键字参数 # 关键字参数解构,key必须是str dict={'x':3,'y':9} add(**dict) #3+9=12
2. 函数定义
2.1 如何定义
def 函数名(参数列表):
执行语句
return 返回值
def add(x, y): # 函数定义 def 表示定义一个函数;紧接着是函数名,函数名后面用一对小括号列出参数列表;参数列表后面使用一个冒号开始函数体 print(x + y) # 函数体是正常的Python语句,可以包含任意结构 return x + y # return语句表示函数的返回值
2.2 函数的参数
2.2.1 普通参数
2.2.2 默认参数
2.2.3 可变参数(*变量 **变量)
2.2.4 keyword-only参数
2.2.5 参数设置规则
# 可以为参数设置默认值,调用时如果不传递此参数,会使用默认值 def inc(x,y=9): print(x+y) inc(1,10) #11 inc(1) #10
# 位置可变参数:*变量 构成元祖,以位置参数的形式传参 def sum(*lst): print(type(lst)) ret=0 for x in lst: ret+=x print(ret) sum(1,2,3,4,5) #<class 'tuple'> #15 sum(1,2,3) #<class 'tuple'> #6 # 关键字可变参数:**变量 构成字典,以关键字参数的形式传参 def connect(**kwargs): print(type(kwargs)) for k,v in kwargs.items(): print('{}——>{}'.format(k,v)) connect(host='127.0.0.1',port=3306) #<class 'dict'> #host——>127.0.0.1 #port——>3306
# 所以如果要创建一个接受任意类型参数的函数,可以如何定义?
def wrap(*args,**kwargs)
# 规则1:普通参数和可变参数可以一起使用,但传参必须匹配 def fn(x,y,*args,**kwargs): print("x=",x) print("y=",y) print("args=",args) print("kwargs=",kwargs) fn(1,2) #x= 1 #y= 2 #args= () #kwargs= {} fn(1,2,0,2,6,a=3,b=9) #x= 1 #y= 2 #args= (0, 2, 6) #kwargs= {'b': 9, 'a': 3} fn(2,y=3) #x= 2 #y= 3 #args= () #kwargs= {} fn(2,3,6,9,x=1) #TypeError: fn() got multiple values for argument 'x' # 规则2:位置可变参数如果放普通参数之前,普通参数会变成keyword-only参数 def fn(*args,x): pass fn(2,3,0) #TypeError: fn() missing 1 required keyword-only argument: 'x' # 规则3:而关键字可变参数就不能在普通参数|默认参数之前 def fn(**kwargs,x): pass #SyntaxError: invalid syntax def fn(**kwargs,x=9): pass #SyntaxError: invalid syntax
# 规则4:不建议可变参数和默认参数一起使用 def fn(*args,x=5): print(args) print(x) fn(1,2,3) #(1, 2, 3) #5 def fn(x=5,*args): print(x) print(args) fn(1,2,2) #1 #(2, 2) # 规则5:位置可变参数和关键字可变参数可以同时使用,但位置可变参数必须在前面 def fn(*args,**kwargs): print(args) print(kwargs) fn(1,2,3,a=3,b=9) #(1, 2, 3) #{'a': 3, 'b': 9} def fn(**kwargs,*args,): pass #SyntaxError: invalid syntax
3. 函数返回值
# 返回值除了返回值的作用外,还会结束函数,return后的语句将不会被执行 # 所以有结束函数作用的需求时,可以直接写“return”即可 def add(x,y): return x+y print("test") print(add(3,9)) #12
# 一个函数可以有多个return,执行到哪个就由哪个返回并结束 def guess(x): if x>3: return '>3' print('end') return '<=3' print('end') print(guess(3)) #<=3 print(guess(9)) #>3
# return可以提前结束循环 # 没有return返回None def fn(x): for i in range(x): if i>=3: return i else: print('not bigger than 3') print(fn(10)) #3 #not bigger than 3 print(fn(2)) #None # return多个值时,可以用封装把返回值封装成一个元组、用解构来获取 def fn(): return 3,5 print(type(fn())) #<class 'tuple'> x,y=fn() print(x,y) #3 5
4.函数作用域
4.1 上下级作用域的变量的关系
# 函数内部是一个局部作用域,对上级作用域(全局作用域)的变量x ——>只读可见,不可操作 x=1 def inc(): x+=1 inc() #UnboundLocalError: local variable 'x' referenced before assignment def inc(): print(x) inc() #1
def fn(): xx=1 print(xx) def inner(): print(xx) #上级作用域的变量对下级作用域是可见的 inner() fn() #1 #1 def fn(): xx=1 print(xx) def inner(): xx=2 #在inner()作用域内定义的变量,那就只对该内部作用域及其下级作用域可见 print(xx) inner() print(xx) fn() #1 #2 #1
4.2 global 标记全局变量
#global 全局变量 xx=2 def fn(): global xx #将上级作用域的xx变量标记为全局变量 xx+=1 #则可对它操作了 fn() print(xx) #3 def fn(): global aa=1 #注意global只能标记,并不能定义变量 aa+=1 fn() #SyntaxError: invalid syntax #除非你清楚的知道global会带来什么,并且明确的知道,非global不行, 否则不要使用global
4.3 nonlocal
def fn(): xx=1 print(xx) def inner(): xx+=1 #对上级作用域定义的xx,原本是不可操作或定义的 print(xx) inner() fn() #UnboundLocalError: local variable 'xx' referenced before assignment def fn(): xx=1 print(xx) def inner(): nonlocal xx #nonlocal可以标记上一级作用域变量,使它可读可写 xx+=1 print(xx) inner() fn() #1 #2
5. 匿名函数(lambda)
5.1 lambda 可以怎样被定义和使用
lambda x:x+1 #<function __main__.<lambda>> print((lambda x:x+1)(5)) #6 f=lambda x:x+1 print(f(5)) #6 # 匿名函数(lambda表达式) 只能写在一行上所以也有人叫它单行函数 f=lambda x: if x <0: 0 else: 0 #SyntaxError: invalid syntax
5.2 lambda支持所有的参数列表及规则
# 匿名函数支持所有普通函数所支持的参数列表及规则 print((lambda :0)()) #0 print((lambda x,y:x+y)(3,5)) #8 print((lambda *args:args)(*range(3))) #(0, 1, 2) print((lambda *args,**kwargs:print(args,kwargs))(*range(3),**{str(x):x for x in range(3)})) #(0, 1, 2) {'0': 0, '2': 2, '1': 1}
5.3 lamdba常和sorted( )等高阶函数一起使用
# 匿名函数通常用于高阶函数的参数,当此函数非常短小的时候,就适合使用匿名函数
6. 生成器函数(yield)
def gen(): print('a') yield 1 print('b') yield 2 return 3 g=gen() print(g) #<generator object gen at 0x7f144845a308> print(next(g)) #a #1 print(next(g)) #b #2 print(next(g)) #StopIteration: 3 # 带yield语句的函数称之为生成器函数, 生成器函数的返回值是生成器
* 生成器函数执行的时候,不会执行函数体
* 当next生成器的时候, 当前代码执行到之后的第一个yield,会弹出值,并且暂停函数
* 当再次next生成器的时候,从上次暂停处开始往下执行
* 当没有多余的yield的时候,会抛出StopIteration异常,异常的value是函数的返回值
更多关于生成器参考:《[PY3]——函数——生成器(yield关键字)》