> A __hash__ method with side effects is not formally prohibited in the > documentation but nevertheless, a __hash__ which is not idempotent is > an abomination.[1] Thus, there is no need for a test of whether __hash__ > will succeed: just try it.
> [1] I subtlely switched language from "side effect free" to "idempotent" > here because caching *IS* acceptable in __hash__ mehtods. If you're > not paying close attention I probably got away with it. Then I went > and spoiled it with a footnote. I picked it up before seeing the footnote :-) I can think of two troublesome cases; there may be others I haven't thought of. 1) An object x with a component y that might be hashable. x is hashable apart from x.y, but hashing x for the first time has side effects, so the value is cached. The hash of x depends partly on the hash of x.y. In other words: def __init__(self): self.hashmem = None def __hash__(self): if not self.hashmem: self.hashmem = self.y.partialhash(self.partialhash()) return self.hashmem If we call x.__hash__, it will try to hash x.y; if that fails, x.__hash__ will raise an exception but the side effect of computing x.partialhash() will already have happened. In other words, even though hashing is idempotent when it succeeds, you may still wish to avoid the side effects of trying to evaluate it if it is going to fail. 2) An object for which computing the hash for the first time requires human action. For example, we might have an object that represents a CD in a CD library. Computing the hash for such an object might require someone to load the CD into a drive so that it can be read. _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com