2012-09-08 19 views
8
私はPythonで位置引数を使用して学習し、また、彼らは、デフォルトの引数を持つまで混合したときに動作を確認しようとしています

: - :使用してデフォルト引数

def withPositionalArgs(ae=9,*args): 
    print 'ae= ', ae 
    print 'args = ', args 


a=1 
b=2 
c=[10,20] 

withPositionalArgs(a,b,c) 

これは私に出力を提供します

ae= 1 
args = (2, [10, 20]) 

aaeの値が渡されたと見なされ、bcは位置引数とみなされます。

だから、私は今withPositionalArgsの呼び出し中にaeため10を割り当てるしようとしています:私はそれを行うことはできません、

withPositionalArgs(ae=10,b,c) 

しかし。私はエラーを取得する:

SyntaxError: non-keyword arg after keyword arg 

私の質問は:私が正しくやっている

?既定の引数が許可されているか、またはPython関数の定位置引数の前に使用することをお勧めしますか?

+2

今、あなたのような何かを行うことができます。 –

+0

"驚くべきこと"は、...(1、ae = 2)が 'TypeError:...()がキーワード引数 'ae'に対して複数の値を取得したことです。 –

答えて

9

Python2では、定位置引数の前にデフォルト値を持つ引数を置くことはできません。

最初に位置指定の引数を指定してから、デフォルト値(または関数を呼び出すときにはキーワード引数)を指定して、次に*args、次に**kwargsを指定する必要があります。

この順序は、関数定義と関数呼び出しの両方に必要です。

Python3では、注文が緩和されました。 (例えば、*argsは、関数定義のキーワード引数の前に来ることができます。)See PEP3102

+0

@unubtu:定義はもちろん、関数呼び出しのどちらでも使用できませんか?または1ヵ所だけ? – GodMan

+0

これは、定義と関数呼び出しの両方で使用する必要がある注文です。関数呼び出しでは 'foo(c = 1、ae = 3、b = 2)'のようなことができます。つまり、引数の順序は、キーワード引数を指定することによって混乱する可能性があります。 – unutbu

+0

私の答えには、Vaughn Catoのコメントから、私は必要に応じて引数を渡すことができ、Pythonは何のエラーも与えません。だから私はあなたの答えを次のように修正しなければならないでしょう: 'Pythonでは、関数呼び出しでは、定位置引数の前にデフォルトパラメータを持つ引数を置くことができません。しかし、あなたは関数定義でそのようにすることは許されていますか? – GodMan

2

デフォルトの値と、任意の引数/キーと値のペアを渡すことの区別をする必要があります。デフォルト値のない動作は同じである:

def f(ae,*args, **kwargs): 
    print 'ae  = ', ae 
    print 'args = ', args 
    print 'kwargs = ', kwargs 

我々はこれを書かれている方法は、最初の引数はそれがf(1,2,3,a=1,b=2)(シーケンスが明示的に引数を行く、* argsを、**は、タプルargsfに渡されることを意味しkwargs。)ここに:ae = 1, args = (2,3), kwargs = {'a': 1, 'b': 2}

aeの値が2回変更されるため、f(1,2,3,a=1,ae=3)を渡そうとすると、TypeError: f() got multiple values for keyword argument 'ae'がスローされます。

。この周り

一つの方法は、唯一のaeを設定することで、それが明示的に規定されている場合、我々可能性(デフ行の後):

def g(*args, **kwargs): 
    kwargs, kwargs_temp = {"ae": 9}, kwargs 
    kwargs.update(kwargs_temp) #merge kwargs into default dictionary 

と今回g(1,2,3,a=1,ae=3)セットargs=(1,2,3), kwargs={a=1,ae=3}

しかし、これはベストプラクティスではないと思われます...

1

Python3はリラックスした順序付けをしています。あなたは `withPositionalArgs(10、B、C)`でそれを呼び出すことができ

def withPositionalArgs(*args, ae=9): 
    print('ae=', ae) 
    print('args =', args) 
a=1 
b=2 
c=[10, 20] 
withPositionalArgs(a, b, c, ae=7) 
関連する問題