【发布时间】:2021-08-13 14:40:40
【问题描述】:
我正在阅读 Luciano Ramalho 的《Fluent Python》一书,我遇到了以下行:
请注意,内置的具体序列类型实际上并不 继承 Sequence 和 MutableSequence 抽象基类 (ABC) 描绘
所以我从 Python 文档中查看了 ABC,但我在理解它们的目的时遇到了问题。
例如,isinstance([], abc.Iterable) 对于列表返回 True,abc.Sequence 和 abc.MutableSequence 也是如此,这是有道理的。对于isinstance 和issubclass 方法,以下内容也是如此。
issubclass(str, abc.MutableSequence) --> False
isinstance((), abc.MutableSequence) --> False
如果我执行以下操作:
class A:
def __iter__(self):
pass
a = A()
isinstance(a, abc.Iterable) # True
issubclass(A, abc.Iterable) # True
但是 A 没有在其类定义中继承 abc.Iterable (并且,根据本书,我假设前面提到的其他类也没有)。 issubclass / isinstance 方法和 ABC 接口如何在这里工作?
这些函数是否只是在类定义中查找 dunder 方法签名并将它们与上述 ABC 类中的 dunder 签名匹配?
除了提供一种验证一个类是否包含某些特定的 dunder 方法的方法之外,我看不出 ABC 类的任何目的,所以很高兴能更多地了解整个过程的目的。
我们将不胜感激任何形式的帮助。谢谢。
【问题讨论】:
-
确实可以不使用 ABC 编写 Python 类,只依赖鸭子类型。你可以在这里找到更多关于为什么要使用 ABC 的讨论:stackoverflow.com/questions/3570796/…
-
这能回答你的问题吗? Why use Abstract Base Classes in Python?
-
虽然在
collections.abc.Iterable的情况下,您可以简单地检查 MRO 中是否存在__iter__,但我认为isinstance(a, abc.Iterable)是一种更好的说法,“我'即将迭代这个对象,让我先检查一下我是否可以做到这一点”。它在类型提示的世界中变得更加有用。
标签: python python-3.x inheritance abc