TypeError:参数有多个值


141

我读了与该错误有关的其他线程,似乎我的问题与到目前为止所读的所有帖子都有一个有趣的明显区别,即,到目前为止,所有其他帖子在创建一个用户方面都存在错误类或内置系统资源。调用函数时遇到此问题,我无法弄清楚它的用途。有任何想法吗?

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'

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

Answers:


222

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

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"作为position和"green"as关键字。(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矩阵。
Tomasz Gandor

嗨,第二个例子我不明白。它还满足条件:When a keyword argument is specified that overwrites a positional argument。但是,为什么后者可以工作?python分配参数时的规则是什么?谢谢。
Alston

2
@斯托曼:我举的第二个例子也是一个无效的例子。color = 20与color =“ green”冲突。分配规则在之后给出。更多信息:docs.python.org/3/tutorial/controlflow.html#keyword-arguments特别是4个“无效调用”示例中的第3个。
Cilyan

70

我遇到的问题确实很容易解决,但花了我一段时间才看穿。

我已经将声明复制到我使用它的地方,并且在此处留下了“自我”的论点,但是我花了很长时间才意识到这一点。

我有

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

但这应该是

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

1
或首先self用类名替换。;)
Tomasz Gandor

49

如果您忘记了self类方法中的声明,也会发生这种情况。

例:

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采用标量,所以缺少自我时参数变乱了,最终输入bc,从而导致“多个参数”错误。我犯了这个错误,是因为我在类外测试了此内部方法,却忘记了添加self回去。希望对其他人有所帮助!
yuqli

@yuqli这也正是我遇到这个问题的方式。;)很高兴得知这篇文章对您有所帮助。
gies0r

1
也为我节省了很多时间:)
nexla

在装饰功能之后@staticmethod也可以使用,当self并非固有需要时,使用它可能是更好的方法。
ayorgo

21

我的问题类似于Q ---十的问题,但是在我的情况下,我忘记了为类函数提供self参数:

class A:
    def fn(a, b, c=True):
        pass

应该成为

class A:
    def fn(self, a, b, c=True):
        pass

当以如下方式调用类方法时,很难看到这种错误的实现:

a_obj = A()
a.fn(a_val, b_val, c=False)

这将产生一个TypeError: got multiple values for argument。希望这里的其余答案很清楚,任何人都可以快速理解并解决错误。如果没有,希望这个答案对您有帮助!


2
哦,老兄,忘记“自我”也是我的问题,这是引发什么误导性的例外
pcko1 19'19

3

简而言之,您不能执行以下操作:

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,一次作为函数声明。


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']值分配给axis,因为它是第一个参数,然后位置参数提供“多个值”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.