id() trickery

Eric Jacobs none at none
Sat Mar 18 16:55:13 EST 2000


In article <Pine.GSO.4.21.0003181444470.17415-100000 at crusoe.crusoe.net>, 
Jeff Pinyan <jeffp at crusoe.net> wrote:
> Well, I've broken my brain again.  Could someone explain this to me?
> 
>>>> a = id(1)
>>>> a, id(1)
> (732968, 732968)
>>>> b = id(1)
>>>> b, id(1)
> (732968, 732968)
>>>> a,b,id(a),id(b)
> (732968, 732968, 732236, 732212)
>>>> a = b + 0
>>>> a,b,id(a),id(b)
> (732968, 732968, 732188, 732212)
>>>> a = b
>>>> a,b,id(a),id(b)
> (732968, 732968, 732212, 732212)
>>>> a = b + 0
>>>> a,b,id(a),id(b)
> (732968, 732968, 732188, 732212)
> 
> Could someone tell me why the value returned by id(), which is just an
> int, says type(), is acting a little fruity for me?  If a and b hold the
> same integer, shouldn't they have the same value for id()?

No. That's not a requirement in the Python object model. The identity of
an object and the value of an object are distinct.

If you're looking for a number which will be equal among objects which
are equal (not identical), you might want to look into the hash
function. Assuming hash is defined,

hash(a) == hash(b)    if and only if    a == b

hash has the additional constraint that its value may never change for
the lifetime of the object. This restricts its use to objects whose
object value is immutable relative to ==, < and >.

> And why do
> 
>>>> a = b # and
>>>> a = b + 0
> 
> have two different effects?

They don't. id() is not an actual method of an object. It's more like an
internal debugging facility. It's not guaranteed to parallel the object's
value as defined by hash, ==, <, etc., or any of the object's other
publicly defined interfaces.

If you're trying to test the "effect" of performing the operator +
with the operand 0 on an object, you've got to put your "blinders" on
and only see through the defined interface -- in this case, it's the
numeric interface, which includes hash and compare, but not id.

Internally, a particular object implementation may decide to intern (recycle)
objects some times and not others, or maybe never at all. In the case of
the integers, only the first 100 whole numbers are interned. That's purely
an implementation decision. When the users of the object look at it through
the public interface, they'll neither know nor care.



More information about the Python-list mailing list