python函數(shù)的參數(shù)*args與**kwargs的區(qū)別

我首先把所有跟python參數(shù)有關(guān)的構(gòu)成方法羅列出來作為printdif的參數(shù),這種構(gòu)成方法可以看成是混合參數(shù)構(gòu)造,是參數(shù)構(gòu)造中最為復(fù)雜的一種方式,作為對講解參數(shù)*args與**kwargs的一個非常棒的方法。代碼如下,仔細(xì)看:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Sat May 20 18:43:07 2017
This demo shows the diffrent arguments between *args and **kwargs
@author: zhangll
"""
class argdemo:
def __init__(self,name):
        self.name=name
def printdif(self,name,key=None,*args,**kwargs):
        self.name=name
        print self.name
        print key
        print  "args=======%s"%str(args)
        count=0
        for value in args:
                count+=1
                print "args's No.%s value:%s"%(count,value)
                print "kwargs=======%s"%str(kwargs)
        for key in kwargs:
                print "**kwargs's key=%s,value=%s"%(key,kwargs[key])
if __name__=='__main__':
        arg=argdemo("name1")
        print arg.name
        arg.printdif("name2","B",["C","D"],{"key1":"E"},key1="hello",key2="world")

最后得到結(jié)果

name2
B
args=======(['C', 'D'], {'key1': 'E'})
args's No.1 value:['C', 'D']
args's No.2 value:{'key1': 'E'}
kwargs======={'key2': 'world', 'key1': 'hello'}
**kwargs's key=key2,value=world
**kwargs's key=key1,value=hello

這個代碼通過調(diào)用arg對象的printdif方法傳遞了共六個參數(shù)

  1. "name2" 字符串
  2. "B" 字符串
  3. ["C","D"] 列表
  4. {"key1":"E"} 字典
  5. key1="hello"
  6. key2="world"

python參數(shù)相關(guān)知識

以上的定義printdif所使用的參數(shù)基本上涵蓋了python的主流參數(shù),根據(jù)主調(diào)函數(shù)**是否必要**傳參的特點上大致把python參數(shù)分為:**必選參數(shù)**與**可選參數(shù)**。關(guān)于這兩種類型的參數(shù)需要做如下語法規(guī)則的補(bǔ)充:
函數(shù)定義與主調(diào)函數(shù)調(diào)用的參數(shù)排序規(guī)則:在必選參數(shù)與可選參數(shù)同時存在的情況下,必須要先定義必選參數(shù),然后再能定義可選參數(shù)------畢竟可選的太多,而必選的參數(shù)是反映函數(shù)功能的主體,當(dāng)然是讓能夠反映函數(shù)主體的元素排在前頭咯。
上面的[name]參數(shù)為**必選參數(shù)**,特點是在函數(shù)定義上,不需要指定內(nèi)容,只需要關(guān)鍵字【name】就行了,但是**主調(diào)函數(shù)**必須要傳入該關(guān)鍵字相關(guān)的內(nèi)容(對象),可以不需要顯式關(guān)鍵字聲明參數(shù),比如可以定義

非顯式關(guān)鍵字:printdif(“abc”)
顯式關(guān)鍵字:printdif(name=“abc”)

調(diào)用函數(shù)結(jié)果
abc
None
args=======()
kwargs======={}

[key=None,\*args,\*\*kwargs]這三個參數(shù)為**可選參數(shù)**,也就是說在主調(diào)函數(shù)中可以不用傳參,上面的必選參數(shù)例子就說明只需要必選參數(shù)的函數(shù)調(diào)用是可以執(zhí)行的。如下,我們關(guān)注的是**可選參數(shù)**的內(nèi)容

1.默認(rèn)參數(shù)又稱關(guān)鍵字參數(shù)(keyword argument):【key=None】在函數(shù)定義的時候已經(jīng)事先定義好了內(nèi)容,key關(guān)鍵字對應(yīng)的是None(相當(dāng)于什么都沒有)內(nèi)容:可以如下調(diào)用主調(diào)函數(shù)

非顯式關(guān)鍵字:printdif(“abc”,“B”)
顯式關(guān)鍵字:printdif(name=“abc”,key=“B”)

調(diào)用函數(shù)結(jié)果:
abc
B
args=======()
kwargs======={}

問題1:printdif(key=“B”,“abc”)這樣的寫法正確嗎?
答案當(dāng)然是錯誤的,因為我們在上面的定義語法要求上說過了,key=“B”其實質(zhì)是一種可選參數(shù)的傳遞,而“abc”為無關(guān)鍵字的必選參數(shù)的傳遞,必選參數(shù)需要放在可選參數(shù)之前,否則會出現(xiàn)
SyntaxError: non-keyword arg after keyword arg
問題2:printdif(“abc”,name=“B”)這樣的寫法正確嗎?
答案當(dāng)然還是錯誤的,這種寫法在直觀上看有重復(fù)調(diào)用參數(shù)的行為,因為我們不僅在定義參數(shù)的語法上有“必選參數(shù)優(yōu)先放在可選參數(shù)之前”的說法,而且在函數(shù)執(zhí)行過程中也有“必選參數(shù)優(yōu)先選擇權(quán)”,也就是說,在執(zhí)行printdif(“abc”,name=“B”)語句的時候,python先執(zhí)行了,“abc”并傳值于name形參,之后又執(zhí)行一遍name=“ B”,也就是又一次重新傳值,就會出現(xiàn)
TypeError: printdif() got multiple values for keyword argument 'name'
因此python拒絕這種多此一舉的行為

2.*args參數(shù) **kwargs參數(shù)
那么為什么我要在最后講解這兩個參數(shù)的區(qū)別呢?這個兩個難道優(yōu)先級最低我才最后講解嗎?其實這兩個參數(shù)還真是在函數(shù)定義優(yōu)先級方面最低(*args參數(shù)優(yōu)先于**kwargs參數(shù)),看printdif的參數(shù)順序就行了,并且這種定義次序不可改變亂了順序,否則會報“語法錯誤”。雖然級別較低,不過這兩種參數(shù)的運(yùn)用確實比較常見的,或者說這種參數(shù)的出現(xiàn),重復(fù)發(fā)揚(yáng)了python參數(shù)傳遞的靈活性,我們拿numpy中的函數(shù)來查看下:

>>>p.fromfunction?
Signature: np.fromfunction(function, shape, **kwargs)
...

大家有沒有發(fā)現(xiàn),在第一個printdif主調(diào)函數(shù)中序列1和2實參分別傳入必選行參與關(guān)鍵字形參,而在分配之后還剩余的實參將會被默認(rèn)分配給*args形參與**kwargs形參。序列3、4參數(shù)作為*args的參數(shù)依次傳遞,而第5、6個做為**kwargs的參數(shù)以字典的形式傳入。從以上這個特點可以發(fā)現(xiàn),*args傳入的參數(shù)不需要賦值命名,并且構(gòu)成元組類型的結(jié)構(gòu),我們稱這種參數(shù)為元組參數(shù)【元組形式:args=(['C', 'D'], {'key1': 'E'})】;而**kwargs需要以命名關(guān)鍵字的實參作為傳入,且構(gòu)成字典類型的結(jié)構(gòu),并且可用key關(guān)鍵字值找到對應(yīng)的參數(shù)內(nèi)容,我們稱這種參數(shù)為字典參數(shù)【字典形式kwargs={'key2': 'world', 'key1': 'hello'}】。

這里有個最后的問題:
如果我調(diào)用printdif(“abc”,“2”,“3”,“4”,key=“B”,key1=“C”),會得到什么結(jié)果?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,415評論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,104評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,647評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,130評論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,366評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,887評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,737評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,174評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,608評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,914評論 2 372

推薦閱讀更多精彩內(nèi)容

  • 兩本不錯的書: 《Python參考手冊》:對Python各個標(biāo)準(zhǔn)模塊,特性介紹的比較詳細(xì)。 《Python核心編程...
    靜熙老師哈哈哈閱讀 3,383評論 0 80
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,781評論 18 139
  • Python 是一種相當(dāng)高級的語言,通過 Python 解釋器把符合語法的程序代碼轉(zhuǎn)換成 CPU 能夠執(zhí)行的機(jī)器碼...
    Python程序媛閱讀 1,928評論 0 3
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,714評論 18 399
  • 被雨淋透了我們 發(fā)尖落下滴噠滴 不忍那份傷感 用溫火烘干愛情 粘上我們的記憶 那份傷感不必答理 我把你記得清晰 請...
    李譯閱讀 194評論 0 3