2

This list показывает, какие методы необходимо реализовать для вашего класса, который будет «рассматривать» в виде последовательности: __getitem__, __len__, __contains__, __iter__, __reversed__, index и count. Итак, почему эта минимальная реализация не работает, а именно, почему issubclass(S, Sequence) is False?issubclass из последовательности абстрактного базового класса

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 return True, конечно, но этот вид поражает идею abc, не так ли?

+0

Просто потому, что класс реализует интерфейс последовательности, не делает его подклассом последовательности. –

+2

Я думаю, что ОП уже это знает. См. [Abc] (https://docs.python.org/2/library/abc.html#module-abc). – Vlad

ответ

4

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 (название которого было изначально «collections.abc.Sequence shoud обеспечить __subclasshook__»). Проблему можно резюмировать, говоря, что последовательность может быть много вещей, в зависимости от потребностей, кто его использует:

Многие алгоритмы, которые требуют последовательности нужно только __len__ и __getitem__. [...] collections.abc.Sequence - это гораздо более богатый интерфейс.

+0

Другими словами collection.Sequence бессмысленна (/ неполна), если не используется как mixin? – kay

+0

@Kay: он дает вам функции многих других абстрактных базовых классов: вы получаете исключение, если пытаетесь наследовать, не определяя все необходимые методы, и вы можете использовать явный 'register()' произвольные подклассы –

+0

Hm, похоже на вопиющее надзор со стороны хакеров Python, чтобы быть честным. Вы знаете причину, почему «Последовательность .__ subclasshook__» не реализована? – kay

 Смежные вопросы

  • Нет связанных вопросов^_^