[Python-Dev] redefining is

Michael Chermside mcherm at mcherm.com
Fri Mar 19 14:55:44 EST 2004


Andrew Koenig writes:
> If I understand the example correctly, every mutable object is also an
> identity object, because you can distinguish between two mutable objects by
> changing one of them and seeing if the other changes.

Nope, that's not what I mean. Check out 
http://mail.python.org/pipermail/python-dev/2004-February/042579.html
for Martin's explanation, which is probably better than mine, but here's
my simple summary:

  Identity Objects: Even if all fields were the same, two instances
    would be considered "different". With Employee objects, if two
    employees both have the name "John Smith", they're still different.

  Value Objects: Object identity is not really important for
    equality. The purpose of these objects is to represent particular
    values. So long as all fields are equal, we consider two such 
    values equal. So two lists are the same if both have the same
    contents. Some value objects (like lists) are mutable, in which
    case the identity MAY be important to distinguish whether the
    objects will remain equal if one is modified; others (like
    strings) are immutable, in which case identity becomes an
    implementation detail (and in some cases like small ints and
    interned strings, cpython takes advantage of this).


You demonstrate case 1:
> 	x = ([], [])
> 	y = ([], [])
> Here, x and y are immutable objects that happen to have mutable attributes.
> Those objects are equal, but not substitutable.

versus case 2:
> 	a = []
> 	b = []
> 	x1 = (a, b)
> 	y1 = (a, b)
> Now: x1 and y1 are mutually substitutable; x and y are equal but not
> mutually substitutable, and x, y, x1, and y1 are all distinct objects.

Interesting. The key here is that "mutable" is used two ways... to mean
that the "top-level-object" (the tuple in your example) is not mutable
and to mean the the entire structure is not mutable. So if I get this
right, you are saying that with these objects:

    >>> v = ([42],)
    >>> w = v
    >>> x = (v[0],)
    >>> y = ([42],)
    >>> z = ([999],)

The '==' operator is useful for distinguishing z from all the others.
The 'is' operator is useful because it distinguishes x from v and w
  (we usually don't care, but it DOES make a difference in memory use).
But no operator exists to distinguish y from v, w, and x. By your
  terminology, v, w, and x are "mutually substitutable", but y is not
  because while it is equal NOW, it might no longer be equal if we
  modified the list.

Whew.... I hadn't realized it was quite so complex. Looking closely
at this, I am beginning to fear that there are not merely _3_ meaningful
forms of equivalence, but far more than that. Of course, the paper
that Peter Norvig referred us to earlier
(http://www.nhplace.com/kent/PS/EQUAL.html) said exactly that. Well,
thanks for clarifying.

-- Michael Chermside




More information about the Python-Dev mailing list