Search code examples
pythonhashiteratorgenerator

Why iterators and generators are hashable?


As title. I mean, you can invoke next(obj) and point to the next element. So the internal state of the iterable or generator will change.

Why they are hashable?


Solution

  • The general rule for hashing objects is:

    1. Unless __eq__ is overridden, object equality is defined by identity, and hashing matches
    2. If __eq__ is overridden, and __hash__ is not, then hashing is blocked by default (because mutability that affects the result of an equality check would break the hash invariants); re-enabling hashing requires implementing __hash__, which implicitly says "My equality and hash semantics are stable/consistent over time", but doesn't require that things not tied to equality or the hash code be stable.

    Point is, the condition for hashability isn't full immutability, it's consistency with equality (and implied stability of both equality and hash). Since most iterators and all generators don't implement __eq__ (there is no meaningful way to implement it without running out the iterator and losing the information you just used to compare it), it's all based on identity, just like with any user-defined object that doesn't define equality.