2013-06-21 43 views
11

考虑以下几点:令人费解的“‘元组’对象不支持项目分配”错误

>>> 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的项目不是一个元组!(事实上预期的分配实际上是成功的,尽管如此,错误消息却使整个场景变得更奇怪)。

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

+1

为什么人们在使用Python常见问题解答之前总是问一个问题?在常见问题解答中,您将得到一个经过多方核心开发人员推理,精心编写和审核的答案,并经受住了时间的考验。就这样,你会得到一个答案,即有人在5分钟内一起打,在接下来的5分钟内重复编辑,然后放弃其余时间。你不喜欢前者吗? – abarnert

+0

@abarnert,因为有无数的方法来问一个问题,而google/stackoverflow结果的捕获远远超过搜索python.org。 SO投出了最广泛的问题网络,当它失败时,问一个问题通常会得到快速反应和积分的回报。在很多情况下,其他更好的资源都与之相关联,因此人们将被指向最佳答案来源。 – dansalmo

回答

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

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所有工作的一个不可避免的结果。虽然任何人不明白这三件事情并不明显,但任何试图改变事物的人都会对确实了解(并可能破坏很多其他更重要的情况)的人更加不明显。

相关问题