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關鍵字)》