[Python-Dev] "is", "==", and sameness
Fri, 12 May 2000 18:05:46 -0400
Greg Weeks wrote:
> >From the Python Reference Manual [emphasis added]:
> Types affect almost all aspects of object behavior. Even the
> importance of object IDENTITY is affected in some sense: for
> immutable types, operations that compute new values may
> actually return a reference to any existing object with the
> same type and value, while for mutable objects this is not
> This seems to be saying that two immutable objects are (in some
> sense) the same iff they have the same type and value, while two
> mutable objects are the same iff they have the same id(). I
> heartily agree, and I think that this notion of sameness is the
> single most useful variant of the "equals" relation.
Notice the "may" in the reference text.
>>> 88 + 11 is 98 + 1
>>> 100 + 3 is 101 + 2
Python goes to the effort of keeping singleton instances of the
integers less than 100. In certain situations, a similar effort is
invested in strings. But it is by no means the general case,
and (unless you've got a solution) it would be expensive to
make it so.
> Indeed, I think it worthwhile to consider modifying the "is"
> operator to compute this notion of sameness. (This would break
> only exceedingly strange user code.) "is" would then be the
> natural comparator of dictionary keys, which could then be any
The implications don't follow. The restriction that dictionary
keys be immutable is not because of the comparison method.
It's the principle of "least surprise". Use a mutable object as a
dict key. Now mutate the object. Now the key / value pair in
the dictionary is inaccessible. That is, there is some pair (k,v)
in dict.items() where dict[k] does not yield v.
> The usefulness of this idea is limited by the absence of
> user-definable immutable instances. It might be nice to be able
> to declare a class -- eg, Point -- to be have immutable
> instances. This declaration would promise that:
> 1. When the expression Point(3.0,4.0) is evaluated, its
> reference count
> will be zero.
That's a big change from the way Python works:
> 2. After Point(3.0,4.0) is evaluated, its attributes will not be
You can make an instance effectively immutable (by messing
with __setattr__). You can override __hash__ to return
something suitable (eg, hash(id(self))), and then use an
instance as a dict key. You don't even need to do the first to
do the latter.