Python函數(shù)的參數(shù)是什么?相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
創(chuàng)新互聯(lián)是創(chuàng)新、創(chuàng)意、研發(fā)型一體的綜合型網(wǎng)站建設(shè)公司,自成立以來公司不斷探索創(chuàng)新,始終堅持為客戶提供滿意周到的服務(wù),在本地打下了良好的口碑,在過去的十多年時間我們累計服務(wù)了上千家以及全國政企客戶,如宴會酒店設(shè)計等企業(yè)單位,完善的項目管理流程,嚴(yán)格把控項目進度與質(zhì)量監(jiān)控加上過硬的技術(shù)實力獲得客戶的一致稱贊。
函數(shù)的靈活性非常高,除了常規(guī)定義的位置參數(shù)以外,還支持默認參數(shù)、關(guān)鍵字參數(shù)、以及可變參數(shù) ... 這樣以來,不但能應(yīng)對各種復(fù)雜的情況,甚至還可以簡化調(diào)用者的代碼。
位置參數(shù)
在調(diào)用函數(shù)時,一般會根據(jù)函數(shù)定義的參數(shù)位置來傳遞參數(shù),這樣的參數(shù)叫做位置參數(shù)。
考慮下面的例子,函數(shù)包含了兩個參數(shù) - name 和 msg:
>>> def greet(name, msg): ... print('Hello, {}, {}!'.format(name, msg)) ...>>>
調(diào)用它很容易:
>>> greet('Pony', 'nice to meet you') Hello, Pony, nice to meet you!
這里,值會按照順序被依次分配。由于“Pony”是第一個值,所以它會被分配給第一個參數(shù) name;同樣地,“nice to meet you”會被分配給第二個參數(shù) msg。
當(dāng)傳遞兩個值時,函數(shù)運行地很順利。但倘若參數(shù)的個數(shù)不匹配,會發(fā)生什么?
>>> greet('Pony') # 少一個參數(shù) ... TypeError: greet() missing 1 required positional argument: 'msg'
顯然,解釋器會發(fā)牢騷。但對 Python 來說,要解決這個問題簡直是易如反掌,繼續(xù)往下看!
默認參數(shù)
在定義函數(shù)時,可以使用賦值運算符(=)為參數(shù)指定默認值:
>>> def greet(name, msg = 'nice to meet you'): ... print('Hello, {}, {}!'.format(name, msg)) ... >>>
注意: 如果參數(shù)沒有默認值,在調(diào)用函數(shù)時必需為其指定一個值;如果有默認值,那么在調(diào)用時值是可選的,如果為其提供了一個值,將會覆蓋默認值。
由于 name 沒有默認值,所以必須指定值,而 msg 有默認值,所以值是可選的:
>>> greet('Pony') # 使用默認值 Hello, Pony, nice to meet you! >>> >>> greet('Pony', 'give me a hug') # 覆蓋默認值 Hello, Pony, give me a hug!
值得注意的是,函數(shù)中的所有參數(shù)都可以有默認值,但是一旦存在一個默認參數(shù),其右側(cè)的所有參數(shù)也必須有默認值。
也就是說,非默認參數(shù)不能在默認參數(shù)之后。例如,像下面這樣,就會報錯:
>>> def greet(msg = 'nice to meet you', name): ... print('Hello, {}, {}!'.format(name, msg)) ... File "", line 1 SyntaxError: non-default argument follows default argument
關(guān)鍵字參數(shù)
為方便起見,Python 還允許使用 key = value 形式的關(guān)鍵字參數(shù)調(diào)用函數(shù):
>>> def greet(name, msg): ... print('Hello, {}, {}!'.format(name, msg)) ...>>>
當(dāng)以這種方式調(diào)用函數(shù)時,所有傳遞的關(guān)鍵字參數(shù)都必須與函數(shù)接受的某個參數(shù)匹配,并且它們的順序不重要:
>>> greet(name = 'Pony', msg = 'nice to meet you') # 按循序傳遞 Hello, Pony, nice to meet you! >>> >>> greet(msg = 'nice to meet you', name = 'Pony') # 順序顛倒也可以 Hello, Pony, nice to meet you!
此外,它還可以和位置參數(shù)混合使用,但關(guān)鍵字參數(shù)必須在位置參數(shù)之后:
>>> greet('Pony', msg = 'nice to meet you') # 位置參數(shù)與關(guān)鍵字參數(shù)混合使用 Hello, Pony, nice to meet you!
所以,如果像下面這樣調(diào)用,就會報錯:
>>> greet(name = 'Pony', message = 'nice to meet you') # message 不存在 ... TypeError: greet() got an unexpected keyword argument 'message' >>> >>> greet(msg = 'nice to meet you', 'Pony') # 關(guān)鍵字參數(shù)不能在位置參數(shù)之前 ... SyntaxError: positional argument follows keyword argument
可變參數(shù)
可變參數(shù)也被稱為不定長參數(shù),顧名思義,就是傳入的參數(shù)個數(shù)是可變的,可以是任意多個(0、1、2 ...)。``
包裹位置傳遞
在參數(shù)名之前可以添加一個星號(*),在函數(shù)內(nèi)部,所有傳入的參數(shù)都會被變量 names 收集,最終按照位置將它們合并為一個元組:
>>> def greet(*names): ... print('Hello,', names) ... >>>
嘗試一下,傳遞不同個數(shù)的參數(shù):
>>> greet() # 沒有參數(shù),為空元組 Hello, () >>> >>> greet('Pony') Hello, ('Pony',) >>> >>> greet('Jack Ma', 'Pony') Hello, ('Jack Ma', 'Pony')
通常情況下,可變參數(shù)(*)會出現(xiàn)在形參列表的最后,因為它們會把傳遞給函數(shù)的所有剩余輸入?yún)?shù)都收集起來:
>>> def greet(msg, *names): ... print('Hello, {}, {}!'.format(names, msg)) ... >>> >>> greet('nice to meet you', 'Jack Ma', 'Pony') Hello, ('Jack Ma', 'Pony'), nice to meet you!
話雖如此,但可變參數(shù)(*)之后還可以出現(xiàn)其它參數(shù),只不過這些形參都是“強制關(guān)鍵字”參數(shù),這意味著,它們只能被用作關(guān)鍵字參數(shù),而不能是位置參數(shù):
>>> def greet(*names, msg): ... print('Hello, {}, {}!'.format(names, msg)) ... >>> >>> greet('Pony', msg = 'nice to meet you') # 只能被用作關(guān)鍵字參數(shù) Hello, ('Pony',), nice to meet you! >>> >>> greet(msg = 'nice to meet you', 'Pony') # 不能被用作位置參數(shù) ... SyntaxError: positional argument follows keyword argument
包裹關(guān)鍵字傳遞
還有一種機制,在參數(shù)名之前添加兩個星號(**),當(dāng)這種形式出現(xiàn)時,msgs 將收集所有關(guān)鍵字參數(shù),最終將它們合并為一個字典:
>>> def greet(**msgs): ... print('Hello,', msgs) ...>>>
和上面一樣,嘗試傳遞不同個數(shù)的參數(shù):
>>> greet() # 沒有參數(shù),為空字典 Hello, {} >>> >>> greet(name = 'Pony') Hello, {'name': 'Pony'} >>> >>> greet(name = 'Pony', msg = 'nice to meet you') Hello, {'name': 'Pony', 'msg': 'nice to meet you'}
此外,*names 還可以與 **msgs 形式的參數(shù)相結(jié)合,但*names 必須出現(xiàn)在 **msgs 之前。
例如,像下面這樣,就會報錯:
>>> def greet(**msgs, *name): ... SyntaxError: invalid syntax
解包裹參數(shù)
正如【可變參數(shù)】那樣,也可在函數(shù)調(diào)用中使用 * 和 **。只不過在這種情況下,與在函數(shù)定義中的語義相反,參數(shù)將被解包裹而不是被包裹:
>>> def greet(name, msg): ... print('Hello, {}, {}!'.format(name, msg)) ... >>>
嘗試一下,元組用 * 來傳遞位置參數(shù):
>>> t = ('Pony', 'nice to meet you') >>> greet(*t) Hello, Pony, nice to meet you!
同樣地,字典也可以用 ** 傳遞關(guān)鍵字參數(shù):``
>>> d = {'name':'Pony', 'msg':'nice to meet you'} >>> greet(**d) Hello, Pony, nice to meet you!
位置參數(shù)、默認參數(shù)、可變參數(shù)混合使用
根據(jù)上面的介紹,我們不難發(fā)現(xiàn),當(dāng)這些參數(shù)混合使用時,應(yīng)遵循一個基本的原則:位置參數(shù) -> 默認參數(shù) -> 包裹位置 -> 包裹關(guān)鍵字(定義和調(diào)用都應(yīng)遵循該順序)。
例如,定義一個函數(shù),能夠同時向多個人發(fā)送多條消息:
>>> def greet(sender, address = 'BeiJing', *receivers, **msgs): ... print('Hello, I am {}, from {}.'.format(sender, address)) ... print('-' * 30) # 華麗的分割線 ... for rec in receivers: ... for key, val in msgs.items(): ... print('No {}: {}, {}!'.format(key, val, rec)) ... print('-' * 30) # 華麗的分割線 ... >>>
為了顯示更好的效果,我們在中間穿插了一些華麗的分割線:
>>> greet('Waleon', 'Xi\'an', 'Jack Ma', 'Pony', one = 'nice to meet you', two = 'give me a hug') Hello, I am Waleon, from Xi'an. ------------------------------ No one: nice to meet you, Jack Ma! No two: give me a hug, Jack Ma! ------------------------------ No one: nice to meet you, Pony! No two: give me a hug, Pony! ------------------------------
看完上述內(nèi)容,你們掌握Python函數(shù)的參數(shù)是什么的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!