抽象基类Sequence的issubclass

发布于 2021-01-29 14:56:00

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

关注者
0
被浏览
117
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    使用消息来源,卢克!

    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是一个更加丰富的界面。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看