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