python中函數的參數
形參:定義函數時代表函數的形式參數
實參:調用函數時傳入的實際參數
列如:
def f(x,y): # x,y形參
print(x, y)
f(1, 2) # 1, 2 實參
定義函數時,形參分為普通參數,預設參數,和動態參數
列如:
複製代碼
def f(x, y): # 普通參數
pass
def f(x, y=1): # y=1是預設參數
pass
def(x,y=1,*args): # *args普通動態參數
pass
def(x,y=1,**kwargs): # **kwargs關鍵字動態參數
pass
複製代碼
調用函數時,根據調用時的寫法,可以分為位置參數和關鍵字參數
複製代碼
def f(x,y):
print(‘x=’,x,’y’=,y)
f(1,2) #我們這樣調用的時候1,2叫位置參數,會根據傳入的實參
#位置去對於形參的位置
輸出結果為:
x= 1 y= 2
f(x=1, y=2)
f(y=2, x=1) #我們這樣調用的時候,y=2,x=1叫做關鍵字參數
#可以不用按照位置寫
複製代碼
那調用的時候同時寫位置參數和關鍵字參數呢
還是以上面的f函數為例
複製代碼
f(x=1, 2) # 當我們吧關鍵字參數放前面
執行結果如下:
File “F:/python/tt.py”, line 9
f(x=1, 2)
SyntaxError: non-keyword arg after keyword arg
複製代碼
得出結論:關鍵字參數不能放在位置參數前面,這個是文法規定
複製代碼
f(1, x=2)
執行結果:
Traceback (most recent call last):
File “F:/python/tt.py”, line 9, in
f(1, x=2)
TypeError: f() got multiple values for keyword argument ‘x’
複製代碼
得出結論:如果位置參數和關鍵字參數需要同時匹配
那麼根據這兩條,我們還可以總結出定義函數時的規範:
1.預設參數要寫在普通參數的後面
2.關鍵字動態參數**kwargs要寫在最後面
我們再來看看動態參數是怎麼啟動並執行:
普通動態參數:
複製代碼
def f(x, *args):
print(args)
f(1, 2, ‘3’, [1, 2, 3])
f(3, 2, [1, 2, 3])
運行結果:
(2, ‘3’, [1, 2, 3])
(2, [1, 2, 3])
複製代碼
普通動態參數會將傳入的所有多餘的位置參數組合成一個元祖
關鍵字動態參數:
複製代碼
def f(x, y=1, **kwargs):
print(kwargs)
f(1, 2, z=2, a=3, d=4)
f(3, 2, xx=2, name=’xinlan’, age=18)
運行結果:
{‘a’: 3, ‘z’: 2, ‘d’: 4}
{‘age’: 18, ‘xx’: 2, ‘name’: ‘xinlan’}
複製代碼
關鍵字動態參數會將傳入的多餘的關鍵字參數組合成一個字典
案例:
複製代碼
d = {
‘name’: ‘xinlan’,
‘age’: 18
}
def f(**kwargs):
print(kwargs)
f(**d)
f(name=’xinlan’, age=18)
運行結果:
{‘name’: ‘xinlan’, ‘age’: 18}
{‘name’: ‘xinlan’, ‘age’: 18}
複製代碼
結論:將一個字典前加上**傳入一個函數,相當於將這個字典中的索引值對以關鍵字參數的形式傳入函數。
案例:
複製代碼
l = [‘python’, ‘php’, ‘java’]
def f(*args):
print(args)
f(*l)
f(‘python’, ‘php’, ‘java’)
運行結果:
(‘python’, ‘php’, ‘java’)
(‘python’, ‘php’, ‘java’)
複製代碼
結論:將一個列表前加上*傳入一個函數,相當於將這個列表中的元素按順序傳入函數
預設參數
預設參數的作用就是,如果我們在調用函數的時候不傳入相應的參數,那麼函數就用預設值
在定義函數的時候我們容易出現一個錯誤,看下面的例子:
複製代碼
def f(y=[]):
y.append(‘ok’)
print(y)
f()
f()
執行結果:
[‘ok’]
[‘ok’, ‘ok’]
複製代碼
我們調用了兩次f函數,發現輸出的結果不一樣。這是因為列表,字典等這樣的資料類型在調用的時候是引用它們的地址。
解譯器在執行y=[]的時候,y指向的一個列表的引用地址,這個列表發生變化後,y指向的地址是沒有變的
所以我們在定義函數的時候,預設參數不要定義成列表,字典等資料類型。當然我們有解決辦法:
複製代碼
def f(y=None): # 這裡None是一個預留位置
if not y:
y = []
y.append(‘ok’)
print(y)
f()
f()
執行結果
[‘ok’]
[‘ok’]
複製代碼