issubclass的抽象基类Sequence

时间:2016-01-21 15:38:45

标签: python subclassing duck-typing isinstance abstract-base-class

This list显示了您需要实施哪些方法才能让您的课程被视为""作为序列:__getitem____len____contains____iter____reversed__indexcount。那么为什么这个最小的实现不起作用,即为什么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 :-(

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

1 个答案:

答案 0 :(得分:8)

Use the source, Luke!

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__的原因,请参阅issue 16728(标题最初是&#34; collections.abc.Sequence shoud提供__subclasshook __&#34 ; )。这个问题可以概括为一个序列可以是很多东西,取决于谁使用它的需要:

  

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

相关问题