14

私は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])

ご覧のとおり、は、にa渡される値であると見なされ、位置引数と見なされます。aebc

だから、私は今、呼び出し10ている間に割り当てようとしています:aewithPositionalArgs

withPositionalArgs(ae=10,b,c)

しかし、私にはできません。エラーが発生します:

SyntaxError: non-keyword arg after keyword arg

私の質問は:

私は正しくやっていますか?デフォルトの引数を許可するか、Python関数の位置引数の前に使用することをお勧めしますか?

4

3 に答える 3

14

Python2では、位置引数の前にデフォルト値を持つ引数を置くことは許可されていません。

位置引数が最初に来て、次にデフォルト値の引数(または、関数を呼び出すときはキーワード引数)、次に、、*argsそして**kwargs

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

Python3では、順序が緩和されました。(たとえば*args、関数定義でキーワード引数の前に置くことができます。)PEP3102を参照してください

于 2012-09-08T15:55:53.523 に答える
4

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

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

fこれを記述した方法は、最初の引数がタプルargsに渡されることを意味しますf(1,2,3,a=1,b=2)(シーケンスは、明示的な引数、*args、**kwargs になります) ae = 1, args = (2,3), kwargs = {'a': 1, 'b': 2}

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

.

これを回避する 1 つの方法は、明示的に規定されている場合にのみ設定aeすることです (def 行の後):

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}

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

于 2012-09-08T16:47:43.767 に答える
1

Python3 では順序付けが緩和されています。

これで、次のようなことができます:

def withPositionalArgs(*args, ae=9):
    print('ae=', ae)
    print('args =', args)
a=1
b=2
c=[10, 20]
withPositionalArgs(a, b, c, ae=7)
于 2017-04-27T18:27:27.523 に答える