令人费解的"'tuple' object does not support item assignment"错误



考虑以下内容:

>>> t = ([],)
>>> t[0].extend([12, 34])
>>> t
([12, 34],)
>>> t[0] += [56, 78]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t
([12, 34, 56, 78],)
>>> 

我知道元组是不可变的,但是 LHS中的项不是元组!(尽管有错误消息,但预期的赋值实际上成功了,这使得整个场景更加奇怪。)

为什么这个行为不被认为是bug?

t[0] += [56, 78]

的缩写
t[0] = t[0].__iadd__([56, 78])

,其中t为元组。t[0].__iadd__([56, 78])部分更改列表,但结果不能存储为t[0]

Python中的LHS总是一个名称,而不是一个值。在每个Python表达式中,RHS被求值并赋值给LHS上的名称。在本例中,不能给名称t[0]赋值,因为t是一个元组。

这在Python FAQ中有文档和解释。

要了解完整的讨论,请阅读FAQ条目。简单地说,问题在于这段代码:

t[0] += [56, 78]

…等价于:

t[0] = t[0].__iadd__([56, 78])

__iadd__成功地修改了list,并返回了自己;然后赋值引发异常。

它不被认为是一个bug,因为它是+=, list.__iadd__tuple工作方式不可避免的结果。对于不理解这三件事的人来说,这是不明显的,但是对于理解的人来说,任何改变事情的尝试都是不明显的(并且可能会破坏许多其他更重要的情况)。

相关内容

最新更新