令人费解的“'元组'对象不支持项目分配”错误

时间:2013-06-21 01:33:56

标签: python

请考虑以下事项:

>>> 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中的项不是元组!(事实上,预期的赋值成功,尽管错误信息,但整个场景只是更多奇异。)

为什么这种行为不被视为错误?

2 个答案:

答案 0 :(得分:8)

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是一个元组。

答案 1 :(得分:2)

记录并解释in the Python FAQ

如需完整讨论,请阅读FAQ条目。但简单来说,问题是这段代码:

t[0] += [56, 78]

......等同于:

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

__iadd__成功修改list就地,并自行返回;然后分配引发了异常。

这是not considered a bug,因为+=list.__iadd__tuple的所有工作都是不可避免的结果。虽然对于那些不理解这三件事情的人来说并不明显,但任何改变事物的尝试对于那些 理解的人来说都是不明显的(而且可能会打破很多其他事情,更多重要的,案例)。