一尘不染

抽象基类Sequence的issubclass

python

这份名单,你需要实现你的类什么方法表示了要被“视为”为序列:__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 :-(

是否有我需要实施的其他方法而被我忽略了?我是否误解了抽象基类?子类化当然Sequenceissubclass返回True,但这有点打败了abc背后的想法,不是吗?


阅读 192

收藏
2021-01-20

共1个答案

一尘不染

使用消息来源,卢克!

Sequence不实现自己的__subclasshook__,并且__subclasshook__的父项的所有实现Sequence都具有如下检查:

class Iterable:
    ...

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

但是,您可以register()将您的班级显式为Sequence

Sequence.register(S)

至于为什么Sequence不实现的原因__subclasshook__,请参见问题16728(标题最初是
“ collections.abc.Sequence应该提供__subclasshook__”
)。可以通过说一个序列来概括这个问题,这取决于谁使用它的需要:

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

2021-01-20