[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