[Edu-sig] python versus __python__

Scott David Daniels Scott.Daniels at Acm.Org
Wed Oct 26 18:13:15 CEST 2005


Beni Cherniavsky wrote:
> On Mon, 2005-10-24 at 20:24 -0700, Scott David Daniels wrote:
> 
> Of course, the proper way to compare object identity is not the
> __low_level__ `id()` function but the ``is`` operator:
> 
>>>>(math.pi + 1.0) is (29. / 7.)
> 
> False
> 
>>>>int('99') is int('99') # small integer
> 
> True
> 
>>>>int('100') is int('100') # big integer
> 
> False
> 
> [``is`` works properly because both expressions are evaluted before the
> ``is`` operator is evaluted and only then the 2 values are
> garbage-collected.  With `id()`, the 2 values could be reclaimed
> immediately because only the address is needed for the ``==``
> comparison.  The fact that `id(foo)` does not reference `foo` is the #1
> source of confusion regarding `id()`.]
That won't save you from surprises when walking in subtle territory.

For example:  # Distributive law
 >>> -(-3 - 7) is (- -3) - -7
True

But:
 >>> -(3 + 7) is -3 - -7
False

The difference is the aforementioned caching trick -- small positive
(and a few negative) integers are cached, the exact range is, I think
-5 : 100, but it is subject to change and should _not_ be remembered
(Python is free to change the number at any time; caching is an
optimization, not meant to affect the meaning of the language).

In general the "is" operator is asking about internals you should seldom
be poking around inside (playing with magic) except for the incantation
"is None" and "is not None" since there is one and only one None.  There
are, of course, times when you are concerned about "exactly this object"
and those times are when is is proper, (and id(obj) might well be a
perfectly fine value supplying a total order on such objects).

The main reason I am belaboring the point is the recent mutable /
immutable discussion: you should never concern yourself with the
identity of an immutable; they are "values" to be compared using
equality or ordering comparisons.  Two immutables built the same way
should be indistinguishable from two references to the same immutable
in properly written code.  You need immutables for dictionary keys,
because (in the implementation) structure is built based on values
of the keys.  If the values changed by mutating, your structure
would no longer reflect the values it contains (so some data would
become unreachable).
     storage = {3+4j : 1, 4+3j : 2}
     Suppose you negated the imaginary part of the object which is the
key to the value 1.

  What should storage[3+4j] (where 3+4j is freshly calculated) return?
  What should storage[3-4j] (where 3-4j is freshly calculated) return?

Such problems are not so much implementation issues (although they do
reveal the implementation) as problems with the definition of the
language.  That's why this is subtle territory.

--Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Edu-sig mailing list