For example, suppose I do this:
>>> class foo(object):
... pass
...
>>> class bar(foo):
... pass
...
>>> some_dict = { foo : 'foo',
... bar : 'bar'}
>>>
>>> some_dict[bar]
'bar'
>>> some_dict[foo]
'foo'
>>> hash(bar)
165007700
>>> id(bar)
165007700
Based on that, it looks like the class is getting hashed as its id number. Therefore, there shouldn't be any danger of worrying about, say, a bar
hashing as either a foo
or a bar
or hash values changing if I mutate the class.
Is this behavior reliable, or are there any gotchas here?
Yes, any object that doesn't implement a __hash__()
function will return its id when hashed. From Python Language Reference: Data Model - Basic Customization :
User-defined classes have
__cmp__()
and__hash__()
methods by default; with them, all objects compare unequal (except with themselves) andx.__hash__()
returnsid(x)
.
However, if you're looking to have a unique identifier, use id
to be clear about your intent. A hash of an object should be a combination of the hashes of its components. See the above link for more details.
Classes have default implementations of __eq__
and __hash__
that use id()
to make comparisons and compute hash values, respectively. That is, they compare by identity. The primary rule for implementing __hash__
methods is that if two objects compare equal to each other, they must also have the same hash value. Hash values can be seen as just an optimization used by dicts and sets to do find equal objects faster. Consequently, if you change __eq__
to do a different kind of equality testing, you must also change your __hash__
implementation to agree with that choice.
Classes that use identity for comparisons can be freely mutated and used in dicts and sets because their identity never changes. Classes that implement __eq__
to compare by value and allow mutation of their values cannot be used in hash collections.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.