Are instances of user-defined classes mutable?

Richard Damon Richard at Damon-Family.org
Thu Aug 6 11:10:34 EDT 2020


On 8/6/20 12:17 AM, ZHAOWANCHENG wrote:
> the doc of dictionary said "if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key."
> i think a instance of user-defined class is mutable, but i found it can be placed into a tuple that as a key of a dict:
>     >>> class mycls(object):
>     ...     a = 1
>     ...
>     >>> me = mycls()
>     >>> me.a = 2  # mutable?
>     >>> {(1, me): 'mycls'}
>     {(1, <__main__.mycls object at 0x0000022824DAD668>): 'mycls'}
>     >>>
>
>
> So are instances of user-defined classes mutable or immutable?
>
That documentation isn't strictly correct. All the elements of the tuple
need to be hashable. Generally imutable objects are hashable and mutable
objects are non-hashable, but user defined classes can be hashable, and
in fact are hashable if they don't define an __eq__ member. Classes
without an __eq__ members, use comparison to id() for equality, so
changing a property hasn't 'mutated' the object as far as the dictionary
is concerned.

Hashability is a key requirement for a dictionary, and for an object to
be properly hashable, its hash must not change over the life of the
object, and two objects that are equal, must have the same hash.

Dictionaries actually need a bit more that just hashable to work right,
dictionaries use the hash of the object to first determine where to
store the item, but then uses the equality relationship. For the
dictionary to work right, the set of other objects that it compares
equal to shouldn't change over the life of the object.

Since by default, user classes use their id() for equality, that meets
that requirement. To find that element in the dictionary, you would need
to build a tuple using that exact same me object, you couldn't create
another object, and set it to the same 'value', as they won't compare equal.

-- 
Richard Damon



More information about the Python-list mailing list