2013-06-21 5 views
11

Betrachten Sie das folgende:Puzzling „‚tuple‘Objekt nicht Gegenstand Zuordnung unterstützen“ Fehler

>>> 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],) 
>>> 

Ich verstehe, dass Tupel unveränderlich sind, sondern das Element in der LHS ist kein Tupel! (Die Tatsache, dass die beabsichtigte Zuweisung in der Tat erfolgreich war, macht trotz der Fehlermeldung das ganze Szenario nur noch bizarrer.)

Warum wird dieses Verhalten nicht als Fehler angesehen?

+1

Warum kommen Leute immer mit einer Frage zu SO, bevor sie in die Python-FAQ gehen? In den FAQ erhalten Sie eine Antwort, die sorgfältig durchdacht, von mehreren Kernentwicklern geprüft und geprüft wurde und die Zeit überdauert hat. Auf SO erhalten Sie die Antwort, dass jemand in 5 Minuten zusammenschlägt, die nächsten 5 Minuten wiederholt bearbeitet und dann den Rest der Zeit abbricht. Hättest du nicht lieber das erstere? – abarnert

+0

@abarnert, weil es unendlich viele Möglichkeiten gibt, eine Frage zu stellen und die google/stackoverflow-Ergebnisse viel mehr fangen als python.org zu suchen. SO wirft das breiteste Frage-Netz und wenn es scheitert, wird das Stellen einer Frage normalerweise mit einer schnellen Antwort und Punkten belohnt. In vielen Fällen sind andere bessere Ressourcen verknüpft, so dass die Leute auf die beste Antwortquelle hingewiesen werden. – dansalmo

Antwort

8
t[0] += [56, 78] 

ist die Abkürzung für

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

wo t ein Tupel ist. Der t[0].__iadd__([56, 78]) Teil ändert die Liste, aber das Ergebnis kann nicht als t[0] gespeichert werden.

Die LHS in Python ist immer ein Name, nie ein Wert. In jedem Python-Ausdruck wird der RHS auf einen Wert ausgewertet und dem Namen auf der LHS zugewiesen. In diesem Fall kann der Name t[0] nicht zugewiesen werden, da t ein Tupel ist.

2

Dies ist dokumentiert und erklärt in the Python FAQ.

Für eine vollständige Diskussion, lesen Sie den FAQ-Eintrag. Aber kurz, das Problem ist, dass dieser Code:

t[0] += [56, 78] 

... entspricht dies:

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

Die __iadd__ erfolgreich die list an Ort und Stelle verändert und kehrt selbst; Dann löst die Aufgabe die Ausnahme aus.

Es ist not considered a bug, weil es eine unvermeidliche Konsequenz davon ist, wie +=, list.__iadd__ und tuple alle funktionieren. Obwohl es für niemanden offensichtlich ist, der diese drei Dinge nicht versteht, wäre jeder Versuch, die Dinge zu ändern, für jemanden, der es nicht versteht, viel unverständlicher (und würde wahrscheinlich viele andere, wichtigere Fälle brechen).

Verwandte Themen