Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

issubclass of abstract base class Sequence

This list shows what methods you need to implement for your class to be "regarded" as Sequence: __getitem__, __len__, __contains__, __iter__, __reversed__, index, and count. So why does this minimal implementation does not work, i.e. why 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 :-(

Is there an additional method I need to implement that I overlooked? Did I misunderstand abstract base classes? Subclassing Sequence makes issubclass return True of course, but that kinda defeats the idea behind abc, doesn't it?

like image 657
kay Avatar asked Jan 21 '16 15:01

kay


People also ask

What is the base class for abstract class?

An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier ( = 0 ) in the declaration of a virtual member function in the class declaration.

What is special about abstract base classes?

Abstract base classes separate the interface from the implementation. They make sure that derived classes implement methods and properties dictated in the abstract base class. Abstract base classes separate the interface from the implementation.

What is abstract base class with example?

Abstract base classes provide a way to define interfaces when other techniques like hasattr() would be clumsy or subtly wrong (for example with magic methods). ABCs introduce virtual subclasses, which are classes that don't inherit from a class but are still recognized by isinstance() and issubclass() functions.

What is an abstract base class ABC )?

Abstract classes are classes that contain one or more abstract methods. An abstract method is a method that is declared, but contains no implementation. Abstract classes cannot be instantiated, and require subclasses to provide implementations for the abstract methods.


1 Answers

Use the source, Luke!

Sequence does not implement its own __subclasshook__, and all the implementations of __subclasshook__ from the parents of Sequence have checks like this:

class Iterable:
    ...

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

You can however explicitly register() your class as a Sequence:

Sequence.register(S)

As for the reason why Sequence does not implement __subclasshook__, see issue 16728 (which title was initially "collections.abc.Sequence shoud provide __subclasshook__"). The issue can be summarized by saying that a sequence can be many things, depending on the needs of who uses it:

Many algorithms that require a sequence only need __len__ and __getitem__. [...] collections.abc.Sequence is a much richer interface.

like image 174
Andrea Corbellini Avatar answered Oct 18 '22 12:10

Andrea Corbellini