列表类如何成为 Python 中 collections.abc.Sequence 的子类?

Phy*_*ade 6 python

在 Python 中,list该类似乎是collections.abc.Sequence(完全有道理的)的子类:

from collections.abc import Sequence
issubclass(list, Sequence)
# returns True
Run Code Online (Sandbox Code Playgroud)

但列表类型似乎没有继承自Sequence

dict.__mro__
# returns (dict, object)
Run Code Online (Sandbox Code Playgroud)

那么,这issubclass(list, Sequence)是如何工作的呢?它如何返回True

alk*_*asm 5

collections.abc类型的重载isinstance()issubclass()运营商检查对象所期待的接口,而无需真正的子类。请参阅PEP 3119,其中介绍了抽象基类;特别是关于重载这两个函数的部分。这是collections.abc模块的重点。例如,如果您定义自己的提供预期属性的类,Python 会说它是该类型的实例/子类:

>>> class MyClass:
...   __contains__ = 0
...
>>> from collections import abc
>>> issubclass(MyClass, abc.Container)
True
Run Code Online (Sandbox Code Playgroud)

检查某物是否是某个其他类型的子类或实例的要点通常是检查它是否具有预期的接口。在这种情况下,MyClass确实有一个__contains__属性,因此假定它符合接口。当然在这个例子中它实际上并不符合接口:MyClass.__contains__它不是一个方法,所以如果你尝试使用一个MyClass()对象作为容器,你的程序将会失败。然而,issubclass()isinstance()会告诉你,这是一个容器对象。通常的鸭子类型规则适用。