Python中实现__contains__的类为何是Container抽象类的实例?
为什么实现
__contains__的类会自动成为Container抽象基类的实例 这个现象的核心原因是collections.abc.Container抽象基类自定义了__subclasshook__校验逻辑,打破了普通抽象基类需要显式继承才能被识别为子类的默认规则:
- 所有
collections.abc下的基础协议类(Container、Iterable、Sized等)都内置了隐式子类识别逻辑,Container的__subclasshook__会校验传入的类是否定义了__contains__方法,只要存在该方法就会直接返回True,判定该类是Container的子类。 - 这种校验逻辑会同时作用于
issubclass()和isinstance()判断,所以你不需要写class Dumb(Container):显式继承,只要实现了对应方法,实例就会被识别为Container类型。
鸭子类型的具体体现
鸭子类型的核心逻辑是不通过继承关系、而是通过对象的实际行为来判定类型归属,对应这个场景的体现非常直观:
- 「容器」这个概念的核心行为就是支持
in运算符判断元素是否存在,而__contains__就是Python中支撑in运算符的底层方法 - 只要一个类实现了
__contains__方法,就说明它具备了容器的核心行为,那就应该被认定为是容器类型,不需要额外的显式继承声明来证明这一点
你可以用以下代码验证这个行为:
from collections.abc import Container # 没有显式继承Container class CustomContainer: def __contains__(self, item): # 自定义包含逻辑,这里简单判断元素是否是偶数 return isinstance(item, int) and item % 2 == 0 print(issubclass(CustomContainer, Container)) # 输出 True print(isinstance(CustomContainer(), Container)) # 输出 True print(3 in CustomContainer()) # 输出 False print(4 in CustomContainer()) # 输出 True
内容的提问来源于stack exchange,提问作者Rosendo Ocaña
相关产品推荐
相关产品推荐

