python可变参数和关键字参数位置_python中函数的默认参数和可变长参数如何排列?...
參數在python中總是通過賦值進行傳遞的。在默認情況下,參數是通過其位置進行匹配的,從左到右,而且必須精確的傳遞和函數頭部參數名一樣多的參數。
這種默認的傳遞方式很簡單
def f(a,b,c):
print(a,b,c)
f(1,2,3)
1 2 3
python中可以使用基于關鍵字的參數匹配形式。在調用函數的時候,能夠更詳盡的定義內容傳遞的位置。關鍵字參數允許通過變量名進行匹配,而不是通過位置。
def f(a,b,c):
print(a,b,c)
f(c=3,a=1,b=2)
1 2 3
我們可以看出,當關鍵字參數使用時參數從左至右的關系已不再重要了,因為參數是通過變量名進行傳遞的,而不是通過其位置。這種調用顯得更文檔化一些(例如使用一些名稱更直觀的參數名)。
甚至在一個調用中混合使用基于位置的參數和基于關鍵字的參數也可以。在這種情況下,所有基于位置的參數首先按照從左到右的順序匹配頭部的參數,之后再進行基于變量名進行關鍵字的匹配。
def f(a,b,c):
print(a,b,c)
f(1,c=3,b=2)
1 2 3
再來說說python中的默認參數形式。默認參數允許創建函數可選的參數,如果沒有傳入值的話,在函數運行前,參數就被賦予了默認值,還是看一個例子:
def f(a,b=2,c=3):
print(a,b,c)
f(1)
1 2 3
f(a=1)
1 2 3
看到這個例子中,我們必須為a提供值,無論是通過位置參數還是關鍵字參數來實現,然而,為b和c提供值是可選的。如果我們不給b和c傳遞值,它們會分別賦值為2和3。
那么按位置順序,當給函數傳遞兩個值的時候,只有c得到默認值,并且當有三個值傳遞時,不會使用默認值。
def f(a,b=2,c=3):
print(a,b,c)
f(1,4)
1 4 3
def f(a,b=2,c=3):
print(a,b,c)
f(1,4,8)
1 4 8
最后一種情況,是關鍵字和默認參數一起使用的情況。關鍵字參數允許我們跳過有默認值的參數,但是要記住的是,首先要完成通過位置進行匹配的參數。
def f(a,b=2,c=3):
print(a,b,c)
f(1,c=6)
1 2 6
很明顯,a通過位置得到了1,c通過關鍵字得到了6,而跳過了b,b通過默認參數得到了2.
有時看到函數定義的參數中有*和**符號,表示什么意思?
這也是python中非常有特色的:當*和**符號出現在函數定義的參數中時,表示任意數目參數收集。
先說說*,他是用元組的形式收集不匹配的位置參數。當這個函數調用時,python將所有位置相關的參數收集到一個新的元組中,并將這個元組賦值給變量args。
def f(a,*args):
print(args)
f(1,2,3,4)
(2, 3, 4)
再說說**的特性,他只對關鍵字參數有效。在這種情況下,**允許將關鍵字參數轉化為字典,你能夠在之后使用鍵調用來進行步進或字典迭代
def f(**kargs):
print(kargs)
f(a=1,b=2)
{'b': 2, 'a': 1}
最后我們來概況一下最一般的形式。即在函數頭部能混合一般參數、*參數以及**去實現更加靈活的調用方式。
def f(a, *pargs, **kargs):
print(a,pargs,kargs)
f(1,2,3,x=4,y=5)
1 (2, 3) {'x': 4, 'y': 5}
這個例子中,1按位置傳給a,2和3收集到pargs位置的元組中,x和y放入kargs關鍵字詞典中
上面是在函數定義的時候寫的*和**形式,那反過來,如果*和**語法出現在函數調用中又會如何呢?他會解包參數的集合。
例如,我們在調用函數時能夠使用*語法,在這種情況下,它與函數定義的意思相反,他會解包參數的集合,而不是創建參數的集合。例如我們可以通過一個元組給一個函數傳遞四個參數,并且讓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)
kargs = {'a':1, 'b':2, 'c':3, 'd':4}
func(**kargs)
1 2 3 4
當然這種形式也是可以混合的,從左到右要以位置參數、元組解包、關鍵字參數、字典解包的順序來進行
def func(a,b,c,d,e,f):
print(a,b,c,d,e,f)
args = (2, 3)
kargs = {'d': 4, 'e': 5}
func(1, *args, f=6, **kargs)
1 2 3 4 5 6
說了這些基本的知識,我們來看看一個實際應用的例子
這種支持任意參數形式的方法的一個應用點,就是實現對其他函數進行靈活調用。因為參數列表可以通過元組、字典形式傳入,所以他支持運行時構建參數列表,這對于測試和計時其他函數非常方便。在下面的代碼中,我們通過傳遞任何發送進來的參數來支持具有任意參數的任意函數:
def tracer(func, *args, **kargs):
print('calling:', func.__name__)
return func(*args, **kargs)
def func(a,b,c,d):
return a+b+c+d
print(tracer(func,1,2,c=3,d=4))
calling: func
10
很明顯,這里在定義tracer函數時應用了收集任意參數的方法,在其中調用func函數時又利用了解包參數的方法。
最后綜合所學,我們舉一個例子,來仿寫一個函數模擬print的功能,他可以接收任意的位置參數,同時接收規定范圍內的關鍵字參數,對多余的關鍵字參數會報錯。
import sys
def print30(*args, **kargs):
sep = kargs.pop('sep', ' ')
end = kargs.pop('end', '\n')
file = kargs.pop('file', sys.stdout)
if kargs:
raise TypeError('extra keywords:{}'.format(kargs))
output = ''
first = True
for arg in args:
output += ('' if first else sep) + str(arg)
first = False
file.write(output + end)
print30('hello','world','healthy',sep='&')
hello&world&healthy
在這段程序中,有幾個關鍵點值得我們注意
對kargs字典進行pop操作,彈出了指定的三個關鍵字sep、end、file后,如果字典里還有值,則證明是多余的關鍵字,程序需要報錯。第二在pop的時候,如果這三個參數如果在調用函數的時候指定了值,就用指定的值,如果沒有指定值則用程序中指定的默認值。
從下面的例子就可以看出,使用多余的關鍵字,程序會報錯。
print30('hello','world','healthy',sep='&',ppp='33',hhh='44')
Traceback (most recent call last):
File "E:/12homework/12homework.py", line 15, in
print30('hello','world','healthy',sep='&',ppp='33',hhh='44')
File "E:/12homework/12homework.py", line 7, in print30
raise TypeError('extra keywords:{}'.format(kargs))
TypeError: extra keywords:{'ppp': '33', 'hhh': '44'}
關于數據科學更系統、更深入的探討可進入我們的專欄《Python數據科學之路》:醬油哥:來吧,一起踏上Python數據科學之路?zhuanlan.zhihu.com
本專欄模仿美劇劇集編排分為五季,第一季:Python編程語言核心基礎、第二季:Python數據分析基本工具、第三季:Python語言描述的數學基礎、第四季:機器學習典型算法專題、第五季:實戰熱點深度應用。
總結
以上是生活随笔為你收集整理的python可变参数和关键字参数位置_python中函数的默认参数和可变长参数如何排列?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑开机后几种常见报错处理方法分享电脑开
- 下一篇: 吃一个月黄瓜能瘦多少