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背后的想法,不是吗?
答案 0 :(得分:8)
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
是一个更丰富的界面。