[Python-Dev] redefining is

Michael Chermside mcherm at mcherm.com
Fri Mar 19 16:20:02 EST 2004


I (Michael Chermside) wrote:
>   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).

Andrew Koenig replies:
> In which case every mutable object is always an identity object.  I did not
> say that every identity object is mutable.  Where is my misunderstanding?

An example of a mutable object which is NOT an identity object is list.

If we have two lists:

    >>> a = [1, 2, 3]
    >>> b = [1, 2, 3]

We want this:

    >>> a == b
    True

to return True. That's because when testing the "equality" of two lists
we only care about their VALUES. It is true that a cannot be substituted
for b in all situations because if we change a the change won't be
reflected in b. But for NOW, they're still equal, because their VALUES
are equal.

An example of an identity object would be an Employee object in a payroll
system.

    >>> class Employee(object):
    ...     def __init__(self, name, department, salary):
    ...         self.name = name
    ...         self.department = department
    ...         self.salary = salary
    ...
    >>> myCubemate = Employee('John Smith', 'IT', 60000)
    >>> guyAcrossHall = Employee('John Smith', 'IT', 60000)
    >>> myCubemate == guyAcrossHall
    False

Despite the fact that my cubemate has the same name as the guy
across the hall... despite the fact that the two objects have
EXACTLY the same value for EACH AND EVERY field, we STILL want
to have the '==' test return False. Because for Employee objects,
two objects are only considered equal if they are the exact same
object. Experienced database designers know whenever they see
an Identity Object to create an "employee_id" field (or its
equivalent) which is guaranteed to be unique, in order to
disambiguate. But in object systems we often just use the object
identity to provide that "identity" which relational databases
lack.

Once again, thanks to Martin for introducing me to this very
useful distinction (although I've done other reading about it
since then) in a discussion over appropriate definitions for 
__eq__ and __hash__.

-- Michael Chermside




More information about the Python-Dev mailing list