list in a tuple
Arnaud Delobelle
arnodel at googlemail.com
Wed Dec 26 13:11:46 EST 2007
On Dec 26, 1:08 am, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> On Mon, 24 Dec 2007 18:01:53 -0800, Raymond Hettinger wrote:
[...]
> > The first succeeds and the second fails.
>
> And this is a good idea?
>
> Shouldn't the tuple assignment raise the exception BEFORE calling
> __iadd__ on the item, instead of after?
If you look at the bytecode generated, this doesn't seem possible:
>>> def f():
... a = ([1],)
... a[0] += [2]
...
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 1 (1)
3 BUILD_LIST 1
6 BUILD_TUPLE 1
9 STORE_FAST 0 (a)
3 12 LOAD_FAST 0 (a)
15 LOAD_CONST 2 (0)
18 DUP_TOPX 2
21 BINARY_SUBSCR
22 LOAD_CONST 3 (2)
25 BUILD_LIST 1
28 INPLACE_ADD
29 ROT_THREE
30 STORE_SUBSCR
31 LOAD_CONST 0 (None)
34 RETURN_VALUE
BINARY_SUBSCR puts a[0] on the stack, it has no way to know that a[0]
will be changed in place. To allow an exception to be thrown before
the in-place modification of a[0], there should be a new bytecode
instruction, say BINARY_SUBSCR_WITH_A_VIEW_TO_CHANGE_IN_PLACE, which
checks that the subscriptable object supports STORE_SUBSCR (;-).
[...]
> I was never a big fan of augmented assignments. I think it goes against
> the Python grain: it's an implied operation, using punctuation, for the
> sole (?) benefit of saving a keystroke or three.
>
> But I think this behaviour counts as a wart on the language, rather than
> a bug.
Yes. I didn't realise this before you mentioned it, but the culprit
here seems to be the augmented assignment which acts differently on
mutable and immutable objects:
b = a # say a is immutable
a += c # equivalent to a = a + c
b is a # -> False
b = a # Now say a is mutable
a += c # equivalent to a.__iadd__(c)
b is a # -> True
OTOH augmented assignent are a slight optimisation:
a[i] += 1
will look for the value of a and i only once and duplicate them on the
stack, whereas
a[i] = a[i] + 1
will need to resolve a and i twice (which can be costly if a and i are
globals)
--
Arnaud
More information about the Python-list
mailing list