class方法生成"TypeError:...为关键字参数获取多个值..."

dre*_*cko 121 python methods class python-2.7

如果我用关键字参数定义一个类方法,那么:

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

调用该方法会生成一个TypeError:

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

...
TypeError: foodo() got multiple values for keyword argument 'thing'
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

dre*_*cko 159

问题是传递给python中的类方法的第一个参数始终是调用该方法的类实例的副本,通常标记为self.如果这样声明了类:

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

它表现得像预期的那样.

说明:

如果没有self作为第一个参数,myfoo.foodo(thing="something")则执行when时,将foodo使用参数调用该方法(myfoo, thing="something").实例myfoo然后被分配给thing(因为thing是第申报参数),但也蟒尝试分配"something"thing的,因此该异常.

要演示,请尝试使用原始代码运行:

myfoo.foodo("something")
print
print myfoo
Run Code Online (Sandbox Code Playgroud)

你输出如下:

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

<__main__.foo object at 0x321c290>
Run Code Online (Sandbox Code Playgroud)

您可以看到'thing'已被赋予对类'foo'的实例'myfoo'的引用.文档的这一部分解释了函数参数的工作原理.

  • 值得注意的是:如果您的函数 def 包含 self 作为第一个参数,然后您不小心也使用 self 作为第一个参数调用该函数,您可能会得到相同类型的错误。 (2认同)

小智 48

感谢有启发性的帖子.我只想留言,如果你得到"TypeError:foodo()得到关键字参数'thing'的多个值,那么你也可能错误地将'self'作为参数传递给了调用该函数(可能是因为你从类声明中复制了这一行 - 当一个人匆忙时这是一个常见的错误).

  • 这就是发生在我身上的事,谢谢你加入这个答案.这可能是更常见的错误,这就是为什么你得到我的upvote. (7认同)

woo*_*oot 27

这可能是显而易见的,但它可能会帮助以前从未见过它的人.如果您错误地按位置分配参数并明确地按名称分配参数,也会发生这种情况.

>>> 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'
Run Code Online (Sandbox Code Playgroud)


小智 6

只需将'staticmethod'装饰器添加到功能中,问题就解决了

class foo(object):
    @staticmethod
    def foodo(thing=None, thong='not underwear'):
        print thing if thing else "nothing" 
        print 'a thong is',thong
Run Code Online (Sandbox Code Playgroud)

  • staticmethod 停止接收 self 作为第一个参数的方法。所以现在,如果你调用 `myfoo.foodo(thing="something")`,thing="something" 将被分配给第一个参数,而不是隐式的 self 参数。 (2认同)

unl*_*kme 6

如果将其中一个键与位置参数相似(具有相同字符串名称)的关键字参数传递给位置参数,也会发生此错误。

>>> 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'
>>> 
Run Code Online (Sandbox Code Playgroud)

“火”已被接受到“酒吧”的论点中。然而,kwargs 中还存在另一个“bar”参数。

在将关键字参数传递给方法之前,您必须从 kwargs 中删除关键字参数。