2012-03-26 103 views
47

在Python中,我可以如下定義一個函數:調用帶有* ARGS一個Python函數,** kwargs和可選/默認參數

def func(kw1=None,kw2=None,**kwargs): 
    ... 

在這種情況下,我可以打電話給FUNC爲:

func(kw1=3,kw2=4,who_knows_if_this_will_be_used=7,more_kwargs=Ellipsis) 

我還可以定義一個函數爲:

def func(arg1,arg2,*args): 
    ... 

其可以被稱爲

func(3,4,additional,arguments,go,here,Ellipsis) 

最後,我可以結合兩種形式

def func(arg1,arg2,*args,**kwargs): 
    ... 

但是,什麼不起作用呼籲:

func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #SYNTAX ERROR (in python 2 only, apparently this works in python 3) 
    ... 

我最初的想法是,這可能是因爲功能

def func(arg1,arg2,*args,kw1=None): 
    ... 

可以被稱爲

func(1,2,3) #kw1 will be assigned 3 

所以這會引入一些含糊不清的3是否應該被包裝成args或kwargs。然而,與Python 3,有指定的關鍵字只有參數的能力:

def func(a,b,*,kw=None): #can be called as func(1,2), func(1,2,kw=3), but NOT func(1,2,3) 
    ... 

有了這個,似乎有沒有語法歧義:

def func(a,b,*args,*,kw1=None,**kwargs): 
    ... 

然而,這仍然帶來了一語法錯誤(用Python3.2測試)。這是我有遺漏的原因嗎?而且,有沒有辦法讓我在上面(有使用默認參數*參數)描述的行爲 - 我知道我可以通過操縱函數內部的kwargs字典模仿這種行爲。

+0

不知道爲什麼你得到「def func(arg1,arg2,* args,kw1 = None,kw2 = None,** kwargs)」的語法錯誤:「 – okm 2012-03-26 13:56:56

+1

@okm因爲我沒有在python 3上測試該版本,只有python 2.我只是假定最終版本會起作用,而當它沒有時,我認爲以前的版本也不起作用。謝謝!。 – mgilson 2012-03-26 14:03:17

+0

裸露的'3'應該如何進入'kwargs'?它會使用什麼關鍵字?我看不出任何含糊之處。請注意,參數列表中的'*'僅在沒有'* args'的情況下才有用。這是一個佔位符,您可以使用*而不是* * args'。 – 2012-03-26 14:45:20

回答

46

可以做關於Python 3

def func(a,b,*args,kw1=None,**kwargs): 

*時要指定關鍵字只有參數只使用沒有接受可變數量的位置參數與*args。你不使用兩個* s。

爲了從語法引用,在Python 2,你必須

parameter_list ::= (defparameter ",")* 
        ( "*" identifier [, "**" identifier] 
        | "**" identifier 
        | defparameter [","]) 

而在Python 3中,你有

parameter_list ::= (defparameter ",")* 
        ( "*" [parameter] ("," defparameter)* 
        [, "**" parameter] 
        | "**" parameter 
        | defparameter [","]) 

,其包括用於所述*參數後附加參數的規定。

4

如果你想要做這兩者的混合記得*指定參數和** kwargs必須是最後指定的參數。

def func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #Invalid 
def func(arg1,arg2,kw1=None,kw2=None,*args,**kwargs): #Valid 

的意見似乎是基於混合了一個函數定義如何相比提供的參數是如何分配回在定義中指定的參數構成。

這是這個函數的定義,它有6個參數。 它通過在函數調用中將命名參數和未命名參數傳遞給它來調用它。

對於這個例子... 當一個參數在調用該函數時被命名時,它可以被無序地提供。 arg1和arg2是必需的參數,如果沒有作爲命名參數傳遞給函數,那麼它們必須按照提供的未命名參數的順序進行分配。 kw1和kw2在函數定義中提供了默認值,所以它們不是強制性的,但如果沒有提供作爲命名參數,它們將從其餘提供的未命名參數中獲取任何可用值。 遺留的所有未命名參數都以名爲args 的數組的形式提供給函數。函數定義中沒有對應參數名稱的任何命名參數都會在名爲kwargs的字典中提供給函數調用。

+5

這在語法上是有效的,但並不像人們所期望的那樣工作,因爲對於額外的必需參數是否映射到命名關鍵字參數或*參數存在歧義。 – tonycpsu 2015-12-20 17:38:49

+2

我會更進一步說,這對於使用Python 2.7製作kw1和kw2'關鍵字'參數不起作用,這就是我來到這裏的原因!表單會更好地列爲'func(arg1,arg2,arg3 = None,arg4 = None,* args,** kwargs):#Valid位置參數默認值,但這實際上只是四個位置參數,兩個這是可選的。要通過kwargs,您需要填寫* all args *,包括arg3和arg4。 – sage 2016-03-22 17:11:55

+2

對於Python 2.7,我建議http://stackoverflow.com/a/15302038/527489並注意'def_val'。 – sage 2016-03-22 17:15:30