'is not' or '!='

Marko Rauhamaa marko at pacujo.net
Tue Aug 19 13:29:52 EDT 2014


Skip Montanaro <skip at pobox.com>:

> The use of "is" or "is not" is the right thing to do when the object
> of the comparison is known to be a singleton.

Object identity stirs a lot of passions on this forum. I'm guessing the
reason is that it is not defined very clearly (<URL:
https://docs.python.org/3/library/functions.html#id>):

   id(object)

       Return the “identity” of an object. This is an integer which is
       guaranteed to be unique and constant for this object during its
       lifetime. Two objects with non-overlapping lifetimes may have the
       same id() value.

       CPython implementation detail: This is the address of the object
       in memory.


The "is" relation can be defined trivially through the id() function:

   X is Y iff id(X) == id(Y)

What remains is the characterization of the (total) id() function. For
example, we can stipulate that:

   X = Y
   assert(id(X) == id(Y))
   # assignment preserves identity

(assuming X and Y are not modified in other threads or signal handlers).

We know further that:

   i = id(X)
   time.sleep(T)
   assert(i == id(X))
   # the identity does not change over time

   def f(x, y):
       return id(x) == id(y)
   assert(f(X, X))
   # parameter passing preserves the identity

   def f(x):
       return x
   assert(id(f(X) == id(X)))
   # the return statement preserves the identity

   assert(id((X0, X1, ..., X)[k]) == id(Xk))
   # tuple composition and projection preserve the identity

   i = id(X)
   X.Y
   assert(i == id(X))
   # reference does not change the identity

and so on. The nice thing about these kinds of formal definitions is
that they make no metaphysical reference to "objects" or "lifetime" (or
the CPython implementation). They can also be converted into
implementation conformance statements and test cases.

A much tougher task is to define when id(X) != id(Y). After all, all of
the above would be satisfied by this implementation of id():

   def id(x):
       return 0

The nonidentity will probably have to be defined separately for each
builtin datatype. For example, for integers and strings we know only
that:

   assert(X == Y or id(X) != id(Y))
   # inequality implies nonidentity


Marko



More information about the Python-list mailing list