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

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

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

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

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

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

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

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

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

1.默認(rèn)參數(shù)又稱關(guān)鍵字參數(shù)(keyword argument):【key=None】在函數(shù)定義的時(shí)候已經(jīng)事先定義好了內(nèi)容,key關(guān)鍵字對(duì)應(yīng)的是None(相當(dāng)于什么都沒(méi)有)內(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======={}

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

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

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容