【问题标题】:TypeError: got multiple values for argumentTypeError:获得多个参数值
【发布时间】:2014-03-12 22:52:15
【问题描述】:

我阅读了与此错误有关的其他线程,似乎我的问题与我迄今为止阅读的所有帖子有一个有趣的明显区别,即到目前为止所有其他帖子都存在关于以下任一错误的错误用户创建的类或内置系统资源。我在调用函数时遇到了这个问题,我不知道它可能是做什么的。有什么想法吗?

BOX_LENGTH = 100
turtle.speed(0)
fill = 0
for i in range(8):
    fill += 1
    if fill % 2 == 0:
        Horizontol_drawbox(BOX_LENGTH, fillBox = False)
    else:
        Horizontol_drawbox(BOX_LENGTH, fillBox = True)

    for i in range(8):
        fill += 1
        if fill % 2 == 0:
            Vertical_drawbox(BOX_LENGTH,fillBox = False)
        else:
            Vertical_drawbox(BOX_LENGTH,fillBox = True)

错误信息:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'

【问题讨论】:

  • Horizontol_drawbox 函数的声明是什么?如果它以fillBox 开头,那就是错误(一次分配位置参数,第二次分配关键字参数)。

标签: python python-3.x


【解决方案1】:

只要使用keyword argumentsargskwargs 的组合调用函数,也会引发此异常

示例:

def function(a, b, c, *args, **kwargs):
    print(f"a: {a}, b: {b}, c: {c}, args: {args}, kwargs: {kwargs}")

function(a=1, b=2, c=3, *(4,))

它会提高:

TypeError                                 Traceback (most recent call last)
<ipython-input-4-1dcb84605fe5> in <module>
----> 1 function(a=1, b=2, c=3, *(4,))

TypeError: function() got multiple values for argument 'a'

而且,每当您在继承中滥用它时,它也会变得更加复杂。所以要小心我们这些东西!

1- 使用keyword argumentsargs 调用函数:

class A:
    def __init__(self, a, b, *args, **kwargs):
        self.a = a
        self.b = b
    
class B(A):
    def __init__(self, *args, **kwargs):

        a = 1
        b = 2
        super(B, self).__init__(a=a, b=b, *args, **kwargs)

B(3, c=2)

例外:

TypeError                                 Traceback (most recent call last)
<ipython-input-5-17e0c66a5a95> in <module>
     11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
---> 13 B(3, c=2)

<ipython-input-5-17e0c66a5a95> in __init__(self, *args, **kwargs)
      9         a = 1
     10         b = 2
---> 11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
     13 B(3, c=2)

TypeError: __init__() got multiple values for argument 'a'

2- 使用 keyword argumentskwargs 调用一个函数,其中也包含关键字参数:

class A:
    def __init__(self, a, b, *args, **kwargs):
        self.a = a
        self.b = b
    
class B(A):
    def __init__(self, *args, **kwargs):

        a = 1
        b = 2
        super(B, self).__init__(a=a, b=b, *args, **kwargs)

B(**{'a': 2})

例外:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-c465f5581810> in <module>
     11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
---> 13 B(**{'a': 2})

<ipython-input-7-c465f5581810> in __init__(self, *args, **kwargs)
      9         a = 1
     10         b = 2
---> 11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
     13 B(**{'a': 2})

TypeError: __init__() got multiple values for keyword argument 'a'

【讨论】:

  • 我不明白这里的解决方案。错误已解释,但未提供解决方案?
【解决方案2】:

我被带到这里的原因到目前为止答案中没有明确提到,所以为了省去别人的麻烦:

如果函数参数更改了顺序,也会发生错误 - 原因与接受的答案相同:位置参数与关键字参数冲突。

在我的例子中,这是因为 Pandas set_axis 函数的参数顺序在 0.20 和 0.22 之间变化:

0.20: DataFrame.set_axis(axis, labels)
0.22: DataFrame.set_axis(labels, axis=0, inplace=None)

使用 set_axis 的常见示例会导致这个令人困惑的错误,因为当您调用时:

df.set_axis(['a', 'b', 'c'], axis=1)

在 0.22 之前,['a', 'b', 'c'] 被分配给轴,因为它是第一个参数,然后位置参数提供“多个值”。

【讨论】:

    【解决方案3】:

    如果您在类方法中忘记了selfdeclaration,也会发生这种情况。

    例子:

    class Example():
        def is_overlapping(x1, x2, y1, y2):
            # Thanks to https://stackoverflow.com/a/12888920/940592
            return max(x1, y1) <= min(x2, y2)
    

    失败self.is_overlapping(x1=2, x2=4, y1=3, y2=5) 一样调用它 与:

    {TypeError} is_overlapping() 得到了参数 'x1' 的多个值

    作品

    class Example():
        def is_overlapping(self, x1, x2, y1, y2):
            # Thanks to https://stackoverflow.com/a/12888920/940592
            return max(x1, y1) <= min(x2, y2)
    

    【讨论】:

    • 这条评论帮助我发现了我的问题:我忘记在函数声明中添加self 参数。即应该是def myFunction(self, a, b, c='123') 写成def myFunction(a, b, c='123')。因为b 接受一个列表,c 接受一个标量,所以当缺少 self 时,参数会变得混乱,最终b 的输入会转到c,从而导致“多个参数”错误。我犯了这个错误是因为我在课堂外测试了这个内部方法,忘记添加self。希望对其他人有帮助!
    • @yuqli 这正是我遇到这个问题的方式。 ;) 很高兴听到这篇文章对您有所帮助。
    • 也为我节省了不少时间 :)
    • 在使用@staticmethod 装饰函数后也可以工作,当self 本身不是必需的时,这可能是更好的方法。
    【解决方案4】:

    简单地说你不能做以下事情:

    class C(object):
        def x(self, y, **kwargs):
            # Which y to use, kwargs or declaration? 
            pass
    
    c = C()
    y = "Arbitrary value"
    kwargs["y"] = "Arbitrary value"
    c.x(y, **kwargs) # FAILS
    

    因为您将变量“y”传递给函数两次:一次作为 kwargs,一次作为函数声明。

    【讨论】:

      【解决方案5】:

      当指定了覆盖位置参数的关键字参数时会发生这种情况。例如,让我们想象一个绘制彩色框的函数。该函数选择要使用的颜色并将框的绘制委托给另一个函数,传递所有额外的参数。

      def color_box(color, *args, **kwargs):
          painter.select_color(color)
          painter.draw_box(*args, **kwargs)
      

      然后调用

      color_box("blellow", color="green", height=20, width=30)
      

      将失败,因为将两个值分配给 color"blellow" 作为位置,"green" 作为关键字。 (painter.draw_box 应该接受 heightwidth 参数)。

      这在示例中很容易看到,但当然如果在调用时混淆了参数,则可能不容易调试:

      # misplaced height and width
      color_box(20, 30, color="green")
      

      这里,color 被分配20,然后args=[30]color 再次被分配"green"

      【讨论】:

      • 有趣 - 当我遇到这个错误时,它也与 color 参数有关。问题有点不同——我的model_matrix 参数变成了仅关键字,一些遗留代码将它作为位置参数传递。新的 API 期待 color,并得到了一个 4x4 矩阵。
      • 嗨,我不明白第二个例子。它也满足条件:When a keyword argument is specified that overwrites a positional argument。但是为什么后一种可以工作呢? python分配参数时的规则是什么。谢谢。
      • @Stallman:我给出的第二个例子也是一个不工作的例子。 color=20 与 color="green" 冲突。分配规则紧随其后。更多信息:docs.python.org/3/tutorial/controlflow.html#keyword-arguments 特别是 4 个“无效调用”示例中的第 3 个。
      • 我在执行此操作时收到此错误:dict(**{'a': 1}, **{'a': 2})。如果我们不重复参数名称,它就可以正常工作:dict(**{'a': 1}, **{'b': 2}).
      • @RoboRobok 确实,这是一种获取错误的“新方法”(3.5),并在python.org/dev/peps/pep-0448/#specification 中进行了描述,我建议您添加自己的问题答案,以便更容易下一位访问者会找到您的建议。
      【解决方案6】:

      我遇到了同样的问题,很容易解决,但我花了一段时间才看透。

      我已将声明复制到我使用它的位置,并将“self”参数留在那里,但我花了很长时间才意识到这一点。

      我有

      self.myFunction(self, a, b, c='123')
      

      但应该是这样的

      self.myFunction(a, b, c='123')
      

      【讨论】:

      • 或者将第一个self替换为类名。 ;)
      • 谢谢。短而窄
      • 在找到您的答案之前,我无法告诉您我挣扎了多久。
      • 我爱你,我一直在挣扎,直到我意识到我在继承之前也复制了方法声明:)
      • 很好的提示,我的问题与调用超级 init 非常相似,并且意外出现了 `super().__init__(self, instance, *args, **kwargs)`而不是super().__init__(instance, *args, **kwargs)
      猜你喜欢
      • 2019-07-05
      • 2019-02-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 2020-04-30
      • 2018-07-28
      • 2022-08-22
      • 2020-02-10
      相关资源
      最近更新 更多