9、函式的引數
位置引數
def func(name, age, gender): print(name, age, gender)
name,age和gender都是函式func的位置引數,位置引數必須被傳值,否則會報錯
關鍵字引數
關鍵字引數指實參,實參以key=value的形式向形參傳值
def func(name, age, gender): print(name, age, gender) # 關鍵字引數說的是實參傳值給形參的方式 func(name='zh', age=18, gender='男')
預設引數
def func(name, gender, age=18):print(name, age, gender)
需要注意:預設引數必須在位置引數之後
預設引數的值在函式定義階段被賦值一次
x = 1 def foo(arg=x): print(arg) x = 5 foo() # 1
預設引數的值應該是不可變型別,如果設定成可變型別,可能會出現下面這種問題
按照理解,每一次的L都應該只有111,但是,隨著函式一直被呼叫,L中的元素不斷變多,因為L在初始化時指向一個不可變物件,這個物件的值被改變,但是不會改變它的記憶體地址,導致L的記憶體地址一致沒有改變,所以元素會越來越多
def foo(L=[]): L.append('111') print(L) foo() # ['111'] foo() # ['111', '111'] foo() # ['111', '111', '111'] foo() # ['111', '111', '111', '111']
如果預設值是不可變型別,就不會有這個問題
def foo(n, arg=None): if arg is None: arg = [] arg.append(n) return arg print(foo(1)) # [1] print(foo(2)) # [2]print(foo(3)) # [3]
可變長度的預設引數
如果在最後一個形參名前加上一個*,那麼在呼叫函式時,溢位的位置實參,都會被接收,以元組的形式儲存下來賦值給這個形參
def foo(x, y, z=1, *args): print(x) print(y) print(z) print(args) foo(1, 2, 3, 4, 5, 6) # 1 # 2 # 3 # (4, 5, 6)
如果事先產生了一個列表,也可以傳入函式
def foo(x, y, z=1, *args): print(x) print(y) print(z) print(args) L = [223, 434, 666] foo(1, 2, 3, *L) # 1 # 2 # 3 # (223, 434, 666)
PS:*在實參的時候作用是打散,在形參的作用是聚合
可變長度的關鍵字引數
如果在最後一個形參名前加**號,那麼在呼叫函式時,溢位的關鍵字引數都會被接收
def foo(x, **kwargs): print(x) print(kwargs) foo(1, y=2, z=3) # 1 # {'y': 2, 'z': 3}
同樣可以用**來打散一個字典
def foo(x, **kwargs): print(x) print(kwargs) dic = {'a': 1, 'b': 2} foo(1, **dic) # 1 # {'a': 1, 'b': 2}
命名關鍵字引數
如果想要限定呼叫者必須以key=value的形式傳遞引數Python3提供了專門的語法:需要在定義形參時,用作為一個分隔符號,號之後的形參稱為命名關鍵字引數。對於這類引數,在函式呼叫時,必須按照key=value的形式為其傳值,且必須被傳值
def foo(name, age, *, height, sex): pass foo('lili', 18, height=1.7, sex='male')
命名關鍵字引數也可以有預設值
如果形參中已經有了可變長度的關鍵字引數,那麼命名關鍵字引數不需要加上*分隔符
def foo(name, age, *args, height, sex): pass
組合使用
所有引數可任意組合使用,但定義順序必須是:位置引數、預設引數、args、命名關鍵字引數、*kwargs
可變引數*args與關鍵字引數kwargs通常是組合在一起使用的,如果一個函式的形參為*args與kwargs,那麼代表該函式可以接收任何形式、任意長度的引數
def foo(*args, **kwargs): pass