web-dev-qa-db-ja.com

* args、** kwargsおよびオプション/デフォルト引数を指定してPython関数を呼び出す

Pythonでは、次のように関数を定義できます。

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)

最後に、2つの形式を組み合わせることができます

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でテスト済み)。私が行方不明になっている理由はありますか?そして、上記の動作を取得する方法はありますか(デフォルト引数で* argsを使用)-関数内のkwargs辞書を操作することでその動作をシミュレートできることはわかっています。

58
mgilson

あなたはcanPython 3。

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

裸の*は、*argsで可変数の位置引数を受け入れるキーワードのみの引数withoutを指定する場合にのみ使用されます。 2つの*を使用しません。

Python 2 の文法から引用するには、

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

Python では、

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

*パラメーターの後に追加パラメーターのプロビジョニングが含まれます。

UPDATE:

最新Python 3ドキュメント ここ

59
agf

両方を混在させたい場合は、* argsと** 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という辞書の関数呼び出しに提供されます。

6
frank