2013-06-21 10 views
11

Si consideri il seguente:sconcertante "oggetto 'tupla' non supporta l'assegnazione voce" errore

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

Capisco che le tuple sono immutabili, ma la voce nel LHS non è una tupla! (Il fatto che l'assegnazione prevista abbia avuto successo, nonostante il messaggio di errore, rende l'intero scenario solo più bizzarro.)

Perché questo comportamento non è considerato un bug?

+1

Perché le persone arrivano sempre a SO con una domanda prima di passare alle Domande frequenti su Python? Nelle Domande frequenti, otterrete una risposta che è stata ragionata, scrupolosamente scritta e controllata da più sviluppatori principali, e ha superato la prova del tempo. Su SO, si ottiene una risposta che qualcuno esegue uno schiaffo in 5 minuti, modifica ripetutamente per i successivi 5 minuti, quindi abbandona per il resto del tempo. Non preferiresti avere il primo? – abarnert

+0

@abarnert, perché ci sono un numero infinito di modi per fare una domanda e i risultati di google/stackoverflow catturano molto più della ricerca di python.org. SO lancia la più ampia rete di domande e quando fallisce, la domanda viene solitamente ricompensata con una risposta veloce e punti. In molti casi sono collegate altre risorse migliori, quindi le persone saranno ricondotte alla migliore fonte di risposta. – dansalmo

risposta

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

è l'abbreviazione di

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

dove t è una tupla. La parte t[0].__iadd__([56, 78]) modifica l'elenco, ma il risultato non può essere archiviato come t[0].

LHS in Python è sempre un nome, mai un valore. In ogni espressione Python, l'RHS viene valutato su un valore e assegnato al nome sul LHS. In questo caso non è possibile assegnare il nome t[0] perché t è una tupla.

2

Questo è documentato e spiegato in the Python FAQ.

Per una discussione completa, leggere la voce delle domande frequenti. Ma in breve, il problema è che questo codice:

t[0] += [56, 78] 

... equivale a questo:

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

Il __iadd__ modifica con successo il list sul posto, e ritorna se stesso; quindi il compito solleva l'eccezione.

E 'not considered a bug, perché è una conseguenza inevitabile di come +=, list.__iadd__ e tuple tutto il lavoro. Anche se non è ovvio per nessuno che non capisce queste tre cose, qualsiasi tentativo di cambiare le cose sarebbe molto più ovvio per chiunque abbia compreso (e probabilmente romperebbe molti altri casi più importanti).

Problemi correlati