Bug or feature?
Robert Brewer
fumanchu at amor.org
Thu Jan 15 01:05:46 EST 2004
Alexey Nezhdanov wrote:
> Hello. Found a strange python behaivoir while writing some
> object. I've
> stripped out all other stuff so the problem is stright here:
> =================================
> #!/usr/bin/python
>
> class Object:
> def __init__(self,val):
> self.val=val
>
> def Sub(self,delta):
> self.val-=delta
> return delta
>
> c=Object(1)
>
> ### case 1 ###
> d=c.Sub(1)
> c.val+=d
> print 'case A:',c.val
>
> ### case 2 ###
> c.val+=c.Sub(1)
> print 'case B:',c.val
> =================================
> Case 1 and case 2 prints out different calues (1 and 2 respectively).
> Do not know - if this is a bug or feature of python.
Disassembly is your friend:
>>> def pluseq(inst):
... inst.val += inst.Sub(1)
...
>>> dis.dis(pluseq)
2 0 LOAD_FAST 0 (inst)
3 DUP_TOP
4 LOAD_ATTR 1 (val)
7 LOAD_FAST 0 (inst)
10 LOAD_ATTR 2 (Sub)
13 LOAD_CONST 1 (1)
16 CALL_FUNCTION 1
19 INPLACE_ADD
20 ROT_TWO
21 STORE_ATTR 1 (val)
24 LOAD_CONST 0 (None)
27 RETURN_VALUE
>>> def subthenplus(inst):
... d = inst.Sub(1)
... inst.val += d
...
>>> dis.dis(subthenplus)
2 0 LOAD_FAST 0 (inst)
3 LOAD_ATTR 1 (Sub)
6 LOAD_CONST 1 (1)
9 CALL_FUNCTION 1
12 STORE_FAST 1 (d)
3 15 LOAD_FAST 0 (inst)
18 DUP_TOP
19 LOAD_ATTR 3 (val)
22 LOAD_FAST 1 (d)
25 INPLACE_ADD
26 ROT_TWO
27 STORE_ATTR 3 (val)
30 LOAD_CONST 0 (None)
33 RETURN_VALUE
As you can see, the order of evaluation in pluseq() is:
load val, call Sub(), add, store result.
whereas the order in subthenplus() is:
call Sub(), load val, add, store result.
...which explains things a bit. If we had written inst.val = inst.val +
inst.Sub(1), the order would be the same as pluseq (but we'd get a
binary add instead of inplace).
Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org
More information about the Python-list
mailing list