可變參數
可變參數允許你傳入0個或任意個參數,這些可變參數在函數調用時自動組裝為一個tuple。
在Python函數中,還可以定義可變參數。顧名思義,可變參數就是傳入的參數個數是可變的,可以是1個、2個到任意個,還可以是0個。
我們以數學題為例子,給定一組數字a,b,c……,請計算a2 + b2 + c2 + ……。
定義函數為:
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum
調用:
print(calc(1,2)) #5
print(calc(1,2,3,4)) #30
把list或tuple的元素變成可變參數傳進去:
nums = [1, 2, 3] nums_2 = (1, 2, 3, 4, 5) print(calc(*nums)) #14
print(calc(*nums_2)) #55
*nums
表示把nums
這個list的所有元素作為可變參數傳進去。
關鍵字參數
關鍵字參數允許你傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝為一個dict。
def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw)
函數person除了必選參數name和age外,還接受關鍵字參數kw。在調用該函數時,可以只傳入必選參數:
person('Michael', 30) #name: Michael age: 30 other: {}
也可以傳入任意個數的關鍵字參數:
person('Bob', 35, city='Beijing') #name: Bob age: 35 other: {'city': 'Beijing'}
person('Adam', 45, gender='M', job='Engineer') #name: Adam age: 45 other: {'job': 'Engineer', 'gender': 'M'}
關鍵字參數可以擴展函數的功能。比如,在person
函數里,我們保證能接收到name
和age
這兩個參數,但是,如果調用者願意提供更多的參數,我們也能收到。
也可以先組裝出一個dict,然后,把該dict轉換為關鍵字參數傳進去:
extra = {'city': 'Beijing', 'job': 'Engineer'} person('Jack', 24, **extra) #name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
**extra
表示把extra
這個dict的所有key-value用關鍵字參數傳入到函數的**kw
參數,kw
將獲得一個dict,注意kw
獲得的dict是extra
的一份拷貝,對kw
的改動不會影響到函數外的extra
。
命名關鍵字參數
如果要限制關鍵字參數的名字,就可以用命名關鍵字參數,例如,只接收city
和job
作為關鍵字參數。這種方式定義的函數如下:
def person(name, age, *, city, job): print(name, age, city, job)
和關鍵字參數**kw不同,命名關鍵字參數需要一個特殊分隔符*,*后面的參數被視為命名關鍵字參數。
調用方式如下:
person('Jack', 24, city='Beijing', job='Engineer') #Jack 24 Beijing Engineer
如果函數定義中已經有了一個可變參數,后面跟着的命名關鍵字參數就不再需要一個特殊分隔符*
了:
def person(name, age, *args, city, job): print(name, age, args, city, job)
命名關鍵字參數必須傳入參數名,如果沒有傳入參數名,調用將報錯:
person('Jack', 24, 'Beijing', 'Engineer')
Traceback (most recent call last): File "E:/ru/231n/exer.py", line 4, in <module> person('Jack', 24, 'Beijing', 'Engineer') TypeError: person() missing 2 required keyword-only arguments: 'city' and 'job'
由於調用時缺少參數名city和job,Python解釋器把這4個參數均視為位置參數,但person()函數僅接受2個位置參數。
命名關鍵字參數可以有缺省值,從而簡化調用:
def person(name, age, *, city='Beijing', job): print(name, age, city, job)
由於命名關鍵字參數city具有默認值,調用時,可不傳入city參數:
person('Jack', 24, job='Engineer') #Jack 24 Beijing Engineer
使用命名關鍵字參數時,要特別注意,如果沒有可變參數,就必須加一個*作為特殊分隔符。如果缺少*,Python解釋器將無法識別位置參數和命名關鍵字參數:
def person(name, age, city, job): # 缺少 *,city和job被視為位置參數
pass