Reference gotcha
Paul Prescod
paul at prescod.net
Mon Feb 9 11:37:15 EST 2004
Ed Schofield wrote:
> Hi all,
> This interested me:
>
>
>>>>a1 = a2 = {}
>>>>a1['blah'] = 1
>>>>a2
>
> {'blah': 1}
>
>>>>a1 == a2
>
> True
A more direct test would be
>>> a1 is a2
True
or
>>> print id(a1)
43243
>>> print id(a2)
43243
>>>>b1 = b2 = 0
>>>>b1 += 1
>>>>b2
>
> 0
>
>>>>b1 == b2
>
> False
>
> So how should one create a robust alias for a numeric type?
b1 _is_ a robust alias for the object "0". It is not an alias for the
variable "b1". Since the object "0" is not changed when you add 1 to the
variable "b1", "b2" is unaffected.
> This bit me when I was trying to do the following in a class:
> def __init__(self, data):
> a = self.a = {}
> b = self.b = {}
> c = self.c = 0
>
> # and increment them here ...
Why wouldn't you just increment "self.c" instead of "c". You could even
rename "self" to "s" so you just need to update "s.c". Alternately you
could update self.c at the bottom of the function after you've done your
computation. But if you want to rebind "self.c" to a new integer value
there is no way to do it except via the "." operator.
Integers are immutable so you can only ever replace a binding to an
integer, never change the integer. It would wreak total havoc if people
could change the integer "0" into "1". Every time you wanted to pass
around an integer you would have to be careful to copy it rather than
merely referencing it.
Interestingly, most people are confused by the fact that list mutations
are shared across references, not by the fact that integers are immutable!
Paul Prescod
More information about the Python-list
mailing list