web-dev-qa-db-ja.com

クラスメソッドは「TypeError:...キーワード引数に複数の値を取得しました...」を生成します

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

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'

どうしたの?

117
drevicko

問題は、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")が実行されると、引数(myfoo, thing="something")を使用してfoodoメソッドが呼び出されます。インスタンスmyfoothingに割り当てられます(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」への参照が割り当てられていることがわかります。 このセクション のドキュメントでは、関数の引数がもう少し機能する方法について説明しています。

156
drevicko

有益な投稿をありがとう。 「TypeError:foodo()が複数のキーワード引数 'thing'の値を取得しました」を取得している場合は、誤って 'self'をパラメーターとして渡している可能性があることに注意してください関数を呼び出します(おそらくクラス宣言から行をコピーしたためです-急いでいるときはよくあるエラーです)。

48
joe_doe

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

>>> 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'
26
woot

関数に 'staticmethod'デコレータを追加するだけで、問題が修正されます

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

私はもう一つ答えを追加したい:

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

there is difference between parameter and argumentここについて詳しく読むことができます pythonの引数とパラメーター

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


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

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

aは位置パラメータです

b = 1はキーワードおよびデフォルトパラメータです

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

そのため、最初にaを位置パラメータとして割り当てます。つまり、位置引数に値を指定する必要があります。ここでは順序が重要です。ただし、呼び出し側の関数の引数aの場所に引数1を渡し、キーワード引数として扱う値をaに提供しています。現在、2つの値があります。

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

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

溶液

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

追加情報

* 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}
4
Aaditya Ura

このエラーは、キーの1つが位置引数に類似している(同じ文字列名を持つ)キーWord引数を渡す場合にも発生する可能性があります。

>>> class Foo():
...     def bar(self, bar, **kwargs):
...             print(bar)
... 
>>> kwgs = {"bar":"Barred", "jokes":"Another key Word argument"}
>>> myfoo = Foo()
>>> myfoo.bar("fire", **kwgs)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() got multiple values for argument 'bar'
>>> 

「火」は「バー」引数に受け入れられました。さらに、kwargsには別の「バー」引数があります。

メソッドに渡す前に、kwargsからキーワード引数を削除する必要があります。

2
unlockme

また、jquery ajaxを使用して「request」パラメータを含まない関数に逆戻りするURLを使用している場合、これはDjangoで発生する可能性があります

$.ajax({
  url: '{{ url_to_myfunc }}',
});


def myfunc(foo, bar):
    ...
1
lukeaus