考虑以下内容:
>>> 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
工作方式不可避免的结果。对于不理解这三件事的人来说,这是不明显的,但是对于理解的人来说,任何改变事情的尝试都是不明显的(并且可能会破坏许多其他更重要的情况)。