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
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a