issubclass的抽象基类Sequence

kay*_*kay 3 python duck-typing subclassing abstract-base-class isinstance

该列表显示了你需要实现你的类方法被"视为"为序列:__getitem__,__len__,__contains__,__iter__,__reversed__,index,和count.那么为什么这个最小的实现不起作用,为什么issubclass(S, Sequence) is False呢?

from collections import *


class S(object):
    def __getitem__(self, item):
        raise IndexError

    def __len__(self):
        return 0

    def __contains__(self, item):
        return False

    def __iter__(self):
        return iter(())

    def __reversed__(self):
        return self

    def index(self, item):
        raise IndexError

    def count(self, item):
        return 0


issubclass(S, Iterable)   # True  :-)
issubclass(S, Sized)      # True  :-)
issubclass(S, Container)  # True  :-)
issubclass(S, Sequence)   # False :-(
Run Code Online (Sandbox Code Playgroud)

我需要实现一个我忽略的额外方法吗?我是否误解了抽象基类?子类化当然Sequenceissubclass回归True,但是那种有点击败了abc背后的想法,不是吗?

And*_*ini 8

使用来源,卢克!

Sequence没有实现自己的__subclasshook__,并且所有__subclasshook__来自父母的实现Sequence都有这样的检查:

class Iterable:
    ...

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:  # <<<<
            if _hasattr(C, "__iter__"):
                return True
        return NotImplemented
Run Code Online (Sandbox Code Playgroud)

但是,您可以register()将您的类明确表示为Sequence:

Sequence.register(S)
Run Code Online (Sandbox Code Playgroud)

至于Sequence没有实现的原因__subclasshook__,请参见问题16728(最初的标题是"collections.abc.Sequence shoud提供__subclasshook__").这个问题可以概括为一个序列可以是很多东西,取决于谁使用它的需要:

许多需要序列的算法只需要__len____getitem__.[...] collections.abc.Sequence是一个更丰富的界面.