请考虑以下事项:
>>> 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中的项不是元组!(事实上,预期的赋值成功,尽管错误信息,但整个场景只是更多奇异。)
为什么这种行为不被视为错误?
答案 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
的所有工作都是不可避免的结果。虽然对于那些不理解这三件事情的人来说并不明显,但任何改变事物的尝试对于那些 理解的人来说都是不明显的(而且可能会打破很多其他事情,更多重要的,案例)。