[Python] Glitch

Daniele Varrazzo piro a develer.com
Ven 4 Gen 2013 15:28:06 CET


On 2013-01-04 15:07, Andrea Ambu wrote:
> OK questo e` _almeno_ controintuitivo.

Sì, lo è, è una piccola verruca :)

> se sostituisci "x[0]" con "a=x[0]; a" oppure sostituendo la riga con 
> += con
> "x[0].__iadd__([3])" non lancia l'eccezione e fa quello che mi 
> aspettavo
> facesse il codice originale.
>
> Cosa mi sto perdendo?

Il codice esegue sia iadd che setitem. Deve farlo perché non è detto 
che iadd non cambi oggetto: iadd della lista restituisce la lista stessa 
perché la cambia inplace, ma questo non è obbligatorio. Vedi 
<http://docs.python.org/2/reference/datamodel.html#object.__iadd__>

Il disassemblato "spiega" tutto:

     >>> T = ([],)
     >>> def f(t, x):
     ...     t[0] += x
     ...
     >>> f(T,[3])
     Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
       File "<stdin>", line 2, in f
     TypeError: 'tuple' object does not support item assignment
     >>> T
     ([3],)
     >>> import dis
     >>> dis.dis(f)
       2           0 LOAD_FAST                0 (t)
                   3 LOAD_CONST               1 (0)
                   6 DUP_TOPX                 2
                   9 BINARY_SUBSCR
                  10 LOAD_FAST                1 (x)
                  13 INPLACE_ADD
                  14 ROT_THREE
                  15 STORE_SUBSCR
                  16 LOAD_CONST               0 (None)
                  19 RETURN_VALUE

INPLACE_ADD chiama iadd della lista, che funziona, ma poi STORE_SUBSCR 
fallisce.

-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com


Maggiori informazioni sulla lista Python