2015-10-15 9 views
6

partialと一緒に使用すると、python3の機能が少し難しいです。他のinfoはキーワードのみの引数です。ここでpython3の関数で '*' "キーワードのみ"引数表記

は私のコードです:ここでは

def awesome_function(a = 0, b = 0, *, prefix): 
    print('a ->', a) 
    print('b ->', b) 
    print('prefix ->', prefix) 
    return prefix + str(a+b) 

は部分の私の理解です:

>>> two_pow = partial(pow, 2) 
>>> two_pow(5) 
32 
>>> 

私は何を理解することは、上記の例であり、partialとしてのみpow関数に二番目の引数になります引数はtwo_powです。

私の質問は、なぜない次の仕事である:

>>> g = partial(awesome_function, prefix='$') 
>>> g(3, 5) 
a -> 3 
b -> 5 
prefix -> $ 
'$8' 
>>> 

しかし、私はこの中にエラーが発生します。

>>> awesome_function(prefix='$', 3, 5) 
    File "<stdin>", line 1 
SyntaxError: non-keyword arg after keyword arg 
>>> 

私は

>>> awesome_function(prefix='$', a = 3, b = 5) 
a -> 3 
b -> 5 
prefix -> $ 
'$8' 
>>> 

答えて

3

、引数のルールが渡されます

argument_list ::= positional_arguments ["," keyword_arguments] 
         ["," "*" expression] ["," keyword_arguments] 
         ["," "**" expression] 
        | keyword_arguments ["," "*" expression] 
         ["," keyword_arguments] ["," "**"  expression] 
        | "*" expression ["," keyword_arguments] ["," "**" expression] 
        | "**" expression 

ここからわかるように、位置指定引数は常に関数呼び出しの先頭に現れます。彼らはどこにも出現できません。あなたは

awesome_function(prefix='$', 3, 5) 

を行うと、あなたがキーワード引数(prefix)の後に2つの位置引数(35)を通過しているとして、それは、上記のルールに違反します。そのため、SyntaxErrorが得られます。これは、Pythonが関数呼び出し式を解析できないためです。


しかし、あなたはpartialを使用しているとき、それは動作しますが、partialは新しい関数オブジェクトを作成し、それに渡されるすべてのパラメータを格納しているため。 partialによって返された関数オブジェクトを実際に呼び出すと、すべての定位置引数が最初に適用され、次にキーワード引数が適用されます。

1

によって直接awesome_functionを呼び出すことができることを知っていますあなたが受け取ったエラー(SyntaxError: non-keyword arg after keyword arg)は、位置的な引数を送信しようとしたためですe 3,5)は、有効な構文ではないため、構文エラーです。 g() - - functools.partialfunctools.partialので、あなたは部分関数を呼び出すときに、したがって、キーワード引数の前に位置引数を置くことを知っている使用している場合、それが動作

awesome_function(prefix='$', 3, 5) 
         ^^^ 
          |  These two are the positional argument. 
          ----- This is the keyword argument.         

- 関数呼び出しで位置引数で、それがキーワードの前に、それらの位置引数を送信します議論。したがって、あなたのケースではg(3, 5) ==> awesome_function(3, 5, prefix='$')です。

単純な例では、この表示する - 私たちはptfunc(20)と呼ばれる上記の場合において、

>>> from functools import partial 
>>> def func(a=0,b=1): 
...  print(a,b) 
... 
>>> ptfunc = partial(func,a=10) 
>>> ptfunc(20) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: func() got multiple values for argument 'a' 

を、20は、最初の位置引数として渡された後、キーワード引数a=10が経過し、従ってそれと不満引数aに複数の値があります。 the documentation -

functools.partialで与えられるよう


ともほぼ同じです:function calls in Pythonのセマンティクスを1として

def partial(func, *args, **keywords): 
    def newfunc(*fargs, **fkeywords): 
     newkeywords = keywords.copy() 
     newkeywords.update(fkeywords) 
     return func(*(args + fargs), **newkeywords) 
    newfunc.func = func 
    newfunc.args = args 
    newfunc.keywords = keywords 
    return newfunc 
関連する問題