Python基础教程:默认参数和可变参数
1. 默認參數
在函數定義時附加一個賦值運算符(=)來為參數指定默認參數值。必選參數在前,默認參數在后,匹配時從左往右進行匹配。
使用默認參數有什么好處?最大的好處是能降低調用函數的難度。
def enroll(name, gender, age=6, city='Beijing'):print('name:', name)print('gender:', gender)print('age:', age)print('city:', city)enroll('Sarah', 'F') enroll('Bob', 'M', 7) # 從左往右匹配,故是age = 7 enroll('Adam', 'M', city='Tianjin') # 可以直接指定賦值的參數名默認參數很有用,但使用不當,也會掉坑里。默認參數有個最大的坑,演示如下:
# 你使用默認參數調用時出現如下情況 print(add_end()) print(add_end()) # 再次調用時結果就不對了 print(add_end())""" output: ['END'] ['END', 'END'] ['END', 'END', 'END'] """原因如下:Python 函數在定義的時候,默認參數 L 的值就被計算出來了,即[],因為默認參數 L 也是一個變量,它指向對象[],每次調用該函數,如果改
變了 L 的內容,則下次調用時,默認參數的內容就變了,不再是函數定義時的[]了。所以,定義默認參數要牢記一點:默認參數必須指向不變對象!
2. 可變參數
可變參數就是傳入的參數個數是可變的,可以是 1 個、2 個到任意個,還可以是 0 個。有以下兩種參數形式:
1)*args:接收N個位置參數,轉換成元組tuple形式。這個*號到底是做什么用的呢?
a. 打包參數:當*號出現在函數參數中時,即遇到帶*號的形參,那么就會把還未分配出去的實參以元組形式打包(pack),分配給那個帶
''' Python學習交流,免費公開課,免費資料, 免費答疑,系統學習加QQ群:579817333 ''' def foo1(*args):print(args) # 輸出 (1, 2, 3, 4, 5)def foo2(a, *args):print('a:', a) print('args:', args) # 輸出 (2, 3, 4, 5)foo1(1, 2, 3, 4, 5) # 1,2,3,4,5被打包分配給args foo2(1, 2, 3, 4, 5) # 1 配給 a, 2,3,4,5被打包分配給args這種打包參數的方法也可以使用在不確定元素個數的情況下的賦值,表述有點抽象,直接看個例子:
# 假如 record 后面都是電話號碼但是不知道有多少個 record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212') name, email, *phone_numbers = record print(phone_numbers) # ['773-555-1212', '847-555-1212']# 最后一個元素會被 current 占用,其余均被打包 *trailing, current = [10, 8, 7, 1, 9, 5, 10, 3] print(trailing) # [10, 8, 7, 1, 9, 5, 10]# 也可用在循環中 records = [('foo', 1, 2), ('bar', 'hello'), ('foo', 3, 4)] def do_foo(x, y):print('foo', x, y)def do_bar(s):print('bar', s)for tag, *args in records:if tag == 'foo':do_foo(*args) # 這里是拆包,可以看下面理解下elif tag == 'bar':do_bar(*args)b. 拆分參數:當*號出現在實參中時,即傳入帶*號的實參,那么會把打包了的實參(元組或列表),拆分成單個的變量,依次賦值給函數的形參。
''' Python學習交流,免費公開課,免費資料, 免費答疑,系統學習加QQ群:579817333 ''' def bar(a, b, c, d=10):print(a, b, c, d)bar(*[1, 2, 3])2)**kwargs:接收N個關鍵字參數,轉換成字典dict形式。**號的作用與*號是一樣的,只是打包或拆分的形式不一樣:
a. 打包參數:對于帶**號的形參,會把多個實參參數打包成字典。
def bar(**kw):print(kw) # 輸出:{'a': 1, 'b': 2, 'c': 3}bar(a=1, b=2, c=3)b. 拆分參數:對于帶**號的實參,會把已經打包的字典的鍵值拆成單個,依次賦值給函數的形參。
def bar(a, b, c):print(a,b,c) # 輸出:1,2,3bar(**{'a': 1, 'b': 2, 'c': 3}) # 每個key必須和bar的形參名一致如果我們希望檢查是否有某個參數,如 city 和 job,可以這樣:
def person(name, age, **kw):if 'city' in kw:# 有 city 參數passif 'job' in kw:# 有 job 參數passprint('name:', name, 'age:', age, 'other:', kw)extra = {'city': 'Beijing', 'job': 'Engineer'} person('Jack', 24, **extra)注:無論函數參數是怎么樣的,我們都可以通過拆分參數這種形式進行賦值,看個例子:
args 和 kw 被拆分后會按順序賦值給 test 的形參。
''' Python學習交流,免費公開課,免費資料, 免費答疑,系統學習加QQ群:579817333 ''' args = (1,2) kw = {}def test(a,b):print(a,b)test(*args, **kw) # 完全不必去管test的參數有幾個或者是怎樣的形式3. 只接受關鍵字參數
將強制關鍵字參數放到某個 *參數或者單個*后面就能達到這種效果。比如:
def recv(maxsize, *, block):'Receives a message'passrecv(1024, True) # TypeError recv(1024, block=True) # Ok總結
以上是生活随笔為你收集整理的Python基础教程:默认参数和可变参数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中的defaultdict函
- 下一篇: Python基础教程:高阶函数和函数嵌套