如何解决实现 __contains__ 方法时从 collections.abc.Container 类隐式继承
所以,我对 Python 有点陌生,对 OOP 范式也有点陌生,最近我遇到了一些似乎有点违反直觉的事情。例如,看看下面的代码(在 Python 3.9 上运行):
from collections.abc import Container
class OddContainer:
def __contains__(self,x):
if not isinstance(x,int) or not x%2:
return False
return True
if __name__ == '__main__':
x = OddContainer()
print(isinstance(x,Container))
这里的print
会输出True
,说明OddContainer
是Container
的子类,但是OddContainer
类没有明确指定其超类。
有人能告诉我这里到底发生了什么吗?说任何具有内部重载 __contains__()
方法的类都成为 Container
类的子类是否正确,还是一种幼稚的解释?如果前者是正确的,那么还有没有其他通过方法重载发生这种继承的情况?
提前致谢。
解决方法
TL;DR isinstance
并非纯粹基于继承。被测试的类可以为自己定义作为类的实例意味着什么。 (不要将“x 是 C 的一个实例”与“x 的类型继承自 C”混淆。)
Container
定义 __subclasshook__
使任何具有 __contains__
方法的类都被视为子类,无论 Container
是否是通过继承的类的实际祖先。
以下是 Python 3.9 中 collections.abc.Container
](https://github.com/python/cpython/blob/3.9/Lib/_collections_abc.py#L388) 的完整定义:
class Container(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __contains__(self,x):
return False
@classmethod
def __subclasshook__(cls,C):
if cls is Container:
return _check_methods(C,"__contains__")
return NotImplemented
__class_getitem__ = classmethod(GenericAlias)
__subclasshook__
优先于继承检查。
在确定某个类 C
是否是 Container
的子类时,会调用 Container.__subclasshook__(C)
。如果 C.__contains__
存在,则返回 True
;如果不是,则返回 False。 (我不确定是否值得深入研究如何调用 Container.__subclasshook__
而 cls
not 是 Container
。)
如果对象参数是 classinfo 参数或其(直接、间接或虚拟)子类的实例,则返回 True。
强调我的。当点击“虚拟”链接时,会导致词汇表中“ABC”的描述指出:
ABC 引入了虚子类,它们是不从类继承但仍被 isinstance() 和 issubclass() 识别的类;请参阅 abc 模块文档。
因此,OddContainer
被认为是一个“虚拟子类”,因为它满足了 Container
ABC。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。