You shouldn’t compare by value but hash by identity. However that would regress them into a list and lead to terrible performance. You can take this property to town by returning a constant hash and make the set or dictionary work purely on equality checks. That means that you can compute your hash over an immutable subset of attributes that may or may not be a unique “primary key” for the instance. Since key lookups are always followed by an equality check, your hashes don’t have to be unique. Hashes can be less picky than equality checks. Python just isn’t conceived with immutability in mind like, say Clojure. Practically speaking though, that’s not always possible – for performance reasons alone. Generally speaking, immutable objects are the cleanest approach and they come with many other upsides your FP-loving friends will happily explain to you at length. If an attribute can change in the lifetime of an object, you can’t use it for hashing or very funky things happen. You can’t base your hash on mutable values. Since that’s not true in our case, we can’t access that object by its hash anymore. In other words: if x = y it must follow that hash(x) = hash(y). Hashable objects which compare equal must have the same hash value. To make matters even more confusing, creating an object with the same hash value will also not work because Python is going to throw a call to _eq_ into the mix and C(1) is clearly not equal to C(2): This explains why all immutable data structures like tuples or strings are hashable while mutable ones like lists or dictionaries aren’t. return f "C( ) # but.it's right there!Īlthough our mutated c clearly is in both d and s, Python claims it never heard of it! Since this is usually good enough, most Pythonistas don’t realize there’s even a thing called hashing until they try to add an unhashable object into a set or a dictionary: As with equality, the inherited object._hash_ method works by identity only: barring the unlikely event of a hash collision, two instances of the same class will always have different hashes, no matter what data they carry. To make a class hashable, it has to implement both the _hash_(self) method and the aforementioned _eq_(self, other) method. Object HashesĪn object hash is an integer number representing the value of the object and can be obtained using the hash() function if the object is hashable. Python 3 is friendly enough to implement an obvious _ne_() for you, if you don’t yourself. By default, those methods are inherited from the object class that compares two instances by their identity – therefore instances are only equal to themselves.Ī common mistake in Python 2 was to override only _eq_() and forget about _ne_().
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |