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)
我需要实现一个我忽略的额外方法吗?我是否误解了抽象基类?子类化当然Sequence会issubclass回归True,但是那种有点击败了abc背后的想法,不是吗?
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是一个更丰富的界面.