Python 3.5 TypeError:参数有多个值[重复]

Posted

技术标签:

【中文标题】Python 3.5 TypeError:参数有多个值[重复]【英文标题】:Python 3.5 TypeError: got multiple values for argument [duplicate] 【发布时间】:2016-11-09 21:43:00 【问题描述】:
def f(a, b, *args):
    return (a, b, args)

f(a=3, b=5)  
(3, 5, ())

而:

f(a=3, b=5, *[1,2,3])  
TypeError: got multiple values for argument 'b'

为什么会这样? 有什么特别的原因吗?

【问题讨论】:

有趣,异常给出了 python 2.7 中的“获取关键字参数'a'的多个值”和 python 3.5 中的“获取参数'b'的多个值” @cdarke 当使用关键字参数时,python 会构建一个 dict 来存储这些参数。 dicts 没有可靠的订单。错误消息中的差异反映了这一点:使用 python2.7 时,hash make 使得 a 是第一个被迭代的键,而在 python3.5 上,它恰好是 b。但这完全取决于字典的构建方式等。 @Bakuriu:我意识到了这一点,但我觉得无论内部实现如何,都应该努力获得一致且有用的错误消息。 “真正的”问题是在位置参数之前使用关键字,这是应该检测和报告的错误。 @cdarke 所以您想在使用该语法时获得SyntaxError?这与大多数 python 不一致,大多数错误都是在运行时引发的。此外,在某些情况下,这样的调用会很好,例如f(a=3, b=5, *[]) 不是问题。同样在一般情况下,如果kwargsargs 中的参数不重叠,f(**kwargs, *args) 仍然可以。最后:python 永远无法确定实际调用的是哪个函数,因此无法先验地确定是否存在重叠。 【参考方案1】:

在文档for calls:

如果语法*expression 出现在函数调用中,则表达式的计算结果必须是可迭代的。来自这些迭代的元素被视为附加的位置参数。对于调用f(x1, x2, *y, x3, x4),如果y 计算结果为序列y1, ..., yM,则这等效于使用M+4 位置参数x1, x2, y1, ..., yM, x3, x4 的调用。

而且,接下来是:

这样做的结果是,尽管*expression 语法可能出现在显式关键字参数之后,但它会在关键字参数之前处理(以及任何**expression arguments –见下文)。

(强调我的)

因此 Python 将首先将 *args 处理为位置参数,将值分配给 b 并使用 b=5 重新分配它,从而导致关键字参数具有多个值的错误。

【讨论】:

【参考方案2】:

问题在于关键字。关键字参数之后不允许使用位置参数。

f(3, 5, *[1,2,3])

工作正常,因为它传递了一个值为 1,2,3 的 元组。同:

f(3, 5, *(1,2,3))

关键字必须始终位于位置参数之后,因此您的函数声明不正确:

def f(*args, a, b):
    return (a, b, args)

print(f(a=3, b=5))
print(f(*[1,2,3], a=3, b=5))

给予:

(3, 5, ())
(3, 5, (1, 2, 3))

【讨论】:

以上是关于Python 3.5 TypeError:参数有多个值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python 3.5 尝试使用 sklearn 和 matplotlib 绘制 PCA

Python - TypeError:需要可迭代参数

TypeError:Python 装饰器的意外关键字参数

Python TypeError:sort()不带位置参数

使用 .net 4.0 测试程序集测试 .net 3.5 程序集时的风险有多大

Python:TypeError:val_dataloader()缺少1个必需的位置参数:'self'