代码之家  ›  专栏  ›  技术社区  ›  Kijewski Jim

抽象基类序列的issubclass

  •  6
  • Kijewski Jim  · 技术社区  · 9 年前

    This list 显示了需要为类实现哪些方法才能“视”为序列: __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 :-(
    

    我是否需要实施我忽略的其他方法?我误解了抽象基类吗?子类别化 Sequence 制造 issubclass 回来 True 当然,但这有点挫败了abc背后的想法,不是吗?

    1 回复  |  直到 9 年前
        1
  •  12
  •   Andrea Corbellini    9 年前

    Use the source, Luke!

    Sequence 不实现自己的 __subclasshook__ ,以及的所有实现 __子类挂钩__ 来自的父母 序列 有这样的支票:

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

    然而,您可以显式地 register() 你的班级 序列 :

    Sequence.register(S)
    

    至于为什么 序列 未实现 __子类挂钩__ 看见 issue 16728 (最初的标题是 “collections.abc.Sequence应提供__subclasshook__” ). 这个问题可以概括为一个序列可以是很多东西,取决于使用它的人的需要:

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