python函數參數傳遞總結


默認參數

def enroll(name, gender, age=6, city='Beijing'):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)

有多個默認參數時,調用的時候,既可以按順序提供默認參數,比如調用enroll('Bob', 'M', 7),意思是,除了name,gender這兩個參數外,最后1個參數應用在參數age上,city參數由於沒有提供,仍然使用默認值。

也可以不按順序提供部分默認參數。當不按順序提供部分默認參數時,需要把參數名寫上。比如調用enroll('Adam', 'M', city='Tianjin'),意思是,city參數用傳進去的值,其他默認參數繼續使用默認值。

def add_end(L=[]):
    L.append('END')
    return L

>>> add_end()
['END''END']
>>> add_end()
['END''END''END']

Python函數在定義的時候,默認參數L的值就被計算出來了,即[],因為默認參數L也是一個變量,它指向對象[],每次調用該函數,如果改變了L的內容,則下次調用時,默認參數的內容就變了,不再是函數定義時的[]了。
定義默認參數要牢記一點:默認參數必須指向不變對象!
要修改上面的例子,我們可以用None這個不變對象來實現:

def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L

可變參數

def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

>>> calc(123)
14
>>> calc(1357)
84

定義可變參數和定義一個list或tuple參數相比,僅僅在參數前面加了一個*號。在函數內部,參數numbers接收到的是一個tuple,因此,函數代碼完全不變。但是,調用該函數時,可以傳入任意個參數,包括0個參數:

>>> calc(12)
5
>>> calc()
0

如果已經有一個list或者tuple,要調用一個可變參數怎么辦?可以這樣做:

>>> nums = [123]
>>> calc(nums[0], nums[1], nums[2])
14

這種寫法當然是可行的,問題是太繁瑣,所以Python允許你在list或tuple前面加一個*號,把list或tuple的元素變成可變參數傳進去:

>>> nums = [123]
>>> calc(*nums)
14

*nums表示把nums這個list的所有元素作為可變參數傳進去。這種寫法相當有用,而且很常見。
關鍵字參數
可變參數允許你傳入0個或任意個參數,這些可變參數在函數調用時自動組裝為一個tuple。而關鍵字參數允許你傳入0個或任意個含參數名的參數,這些關鍵字參數在函數內部自動組裝為一個dict。請看示例:

def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)

>>> person('Adam'45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender''M''job''Engineer'}
>>> 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

命名關鍵字參數必須傳入參數名,這和位置參數不同。如果沒有傳入參數名,調用將報錯:

>>> person('Jack'24'Beijing''Engineer')
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
TypeError: person() takes 2 positional arguments but 4 were given

組合參數
在Python中定義函數,可以用必選參數、默認參數、可變參數、關鍵字參數和命名關鍵字參數,這5種參數都可以組合使用。但是請注意,參數定義的順序必須是:必選參數、默認參數、可變參數、命名關鍵字參數和關鍵字參數。
def f1(a, b, c=0, *args, **kw):

>>> f1(12)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(12, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(123'a''b')
a = 1 b = 2 c = 3 args = ('a''b') kw = {}
>>> f1(123'a''b', x=99)
a = 1 b = 2 c = 3 args = ('a''b') kw = {'x'99}
>>> f2(12, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext'None}

最神奇的是通過一個tuple和dict,你也可以調用上述函數:

>>> args = (1234)
>>> kw = {'d'99'x''#'}
>>> f1(*args, **kw)
a = 1 b = 2 c = 3 args = (4,) kw = {'d'99'x''#'}
>>> args = (123)
>>> kw = {'d'88'x''#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x''#'}

所以,對於任意函數,都可以通過類似func(*args, **kw)的形式調用它,無論它的參數是如何定義的。
偏函數

import functools
int2 = functools.partial(int, base=2)
>>> int2('1000000')
64

簡單總結functools.partial的作用就是,把一個函數的某些參數給固定住(也就是設置默認值),返回一個新的函數,調用這個新函數會更簡單。
偏函數也是用到args,*kw,將參數傳遞給所固定的函數,前提是所固定的函數要有該參數。

個人公眾號,有精選的學習資料,關注即可獲得噢。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM