学习abc模块时为何空类被判定为Hashable抽象基类的实例?
abc.Hashable? Great question! Let's break down why your code returns True step by step.
1. How abc.Hashable checks for membership
The abc.Hashable abstract base class (ABC) doesn't rely solely on explicit inheritance to recognize a type as hashable. Instead, it uses a __subclasshook__ method to perform a dynamic check: it verifies if the target class has a valid __hash__ method.
2. Default behavior of user-defined classes
When you define an empty class like foo without overriding any methods:
- It inherits all default methods from
object, including__hash__and__eq__. - Since you haven't overridden
__eq__, Python keeps the default__hash__method intact. (Note: If you did override__eq__without providing a custom__hash__, Python would automatically set__hash__ = Nonefor the class.)
3. Applying this to your code
When you run isinstance(foo, abc.Hashable):
- The check isn't targeting instances of
foo—it's examining the class objectfooitself. - The
fooclass retains the valid__hash__method inherited fromobject, soabc.Hashable's subclass hook recognizes it as a hashable type. - That's why the result is
True.
Let's test this with a modification
If you override __eq__ without defining __hash__, the result will change:
from collections import abc class foo: def __eq__(self, other): return isinstance(other, foo) print(isinstance(foo, abc.Hashable)) # False
Here, Python sets foo.__hash__ = None because we defined __eq__ but not __hash__, so abc.Hashable no longer recognizes the class as hashable.
Summary
The core point is that abc.Hashable uses structural subtyping (checking for the presence of required methods) rather than just explicit inheritance. Your empty class keeps the default __hash__ method from object, so it passes the hashable check.
内容的提问来源于stack exchange,提问作者yoyoyoyo123

