Подкласс абстрактного базового класса Sequence
Этот список показывает, какие методы вам нужно реализовать, чтобы ваш класс "рассматривался" как Sequence: __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 ответ
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 (название которого изначально было "collection.abc.Sequence shoud обеспечить __subclasshook__"). Проблема может быть подытожена, сказав, что последовательность может состоять из множества вещей, в зависимости от потребностей того, кто ее использует:
Многие алгоритмы, которые требуют только последовательности
__len__
а также__getitem__
, [...]collections.abc.Sequence
гораздо более богатый интерфейс.