142

キーワード引数を使用してクラスメソッドを定義すると、次のようになります。

class foo(object):
  def foodo(thing=None, thong='not underwear'):
    print thing if thing else "nothing" 
    print 'a thong is',thong

メソッドを呼び出すと、次のものが生成されますTypeError

myfoo = foo()
myfoo.foodo(thing="something")

...
TypeError: foodo() got multiple values for keyword argument 'thing'

どうしたの?

4

7 に答える 7

171

問題は、Python でクラス メソッドに渡される最初の引数が、常に、メソッドが呼び出されるクラス インスタンスのコピーであり、通常は というラベルが付けられていることselfです。クラスが次のように宣言されている場合:

class foo(object):
  def foodo(self, thing=None, thong='not underwear'):
    print thing if thing else "nothing" 
    print 'a thong is',thong

期待どおりに動作します。

説明:

self最初のパラメーターとして指定しない場合、myfoo.foodo(thing="something")が実行されると、foodoメソッドは引数付きで呼び出されます(myfoo, thing="something")。次に、インスタンスmyfooがに割り当てられますthing(thingが最初に宣言されたパラメーターであるため) が、python も に割り当てようとする"something"ためthing、例外が発生します。

実証するために、元のコードでこれを実行してみてください。

myfoo.foodo("something")
print
print myfoo

次のように出力されます。

<__main__.foo object at 0x321c290>
a thong is something

<__main__.foo object at 0x321c290>

「thing」には、クラス「foo」のインスタンス「myfoo」への参照が割り当てられていることがわかります。ドキュメントのこのセクションでは、関数の引数がどのように機能するかをもう少し説明します。

于 2013-09-23T00:08:45.833 に答える
50

有益な投稿をありがとう。「TypeError: foodo() got multiple values for keyword argument 'thing'」が発生した場合は、誤って「self」をパラメーターとして渡している可能性もあります。関数を呼び出しています (おそらく、クラス宣言から行をコピーしたためです。急いでいるときによくあるエラーです)。

于 2014-07-24T20:27:57.010 に答える
30

これは明らかかもしれませんが、これまでに見たことがない人にとっては役立つかもしれません。これは、誤って位置によって、明示的に名前によってパラメーターを割り当てた場合に、通常の関数でも発生します。

>>> def foodo(thing=None, thong='not underwear'):
...     print thing if thing else "nothing"
...     print 'a thong is',thong
...
>>> foodo('something', thing='everything')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foodo() got multiple values for keyword argument 'thing'
于 2015-08-05T03:20:54.053 に答える
4

もう1つ答えを追加したい:

関数の呼び出しで、キーワード引数とともに間違った位置順序で位置パラメーターを渡そうとすると発生します。

there is difference between parameter and argumentここで詳細を読むことができますArguments and Parameter in python

def hello(a,b=1, *args):
   print(a, b, *args)


hello(1, 2, 3, 4,a=12)

3 つのパラメーターがあるため:

a は位置パラメータです

b=1 はキーワードであり、デフォルトのパラメータです

*args は可変長パラメータです

そのため、最初に を位置パラメータとして割り当てます。これは、位置引数に値をその位置の順序で提供する必要があることを意味します。ここでは順序の問題です。しかし、呼び出し関数の a の場所で引数 1 を渡し、キーワード引数として扱い、 a にも値を提供しています。今は2つの値があります:

1 つは位置値です: a=1

2 番目は a=12 のキーワード値です

解決

a は 1 である 1 つの位置値のみを取得し、b は値 2 を取得し、残りの値は *args (可変長パラメーター) を取得するように変更hello(1, 2, 3, 4,a=12)する必要があります。hello(1, 2, 3, 4,12)

追加情報

*args が 2,3,4 になり、a が 1 になり、b が 12 になるようにしたい場合

次に、このようにすることができます
def hello(a,*args,b=1): pass hello(1, 2, 3, 4,b=12)

もっと何か :

def hello(a,*c,b=1,**kwargs):
    print(b)
    print(c)
    print(a)
    print(kwargs)

hello(1,2,1,2,8,9,c=12)

出力:

1

(2, 1, 2, 8, 9)

1

{'c': 12}
于 2016-10-10T11:56:22.463 に答える