Post

abc module in Python

abc module in Python

Introduction

abc is short for Abstract Base Class. Usually we use it to create a base class and force the subclass to implement certain functions. In python, abc is similar to C++’s abstract class.

There are three ways we can create this kind of class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from abc import ABC, ABCMeta
from abc import abstractmethod

class Base1(ABC):
    @abstractmethod
    def hi(self):
         raise NotImplementedError("HH")

class Base2(metaclass=ABCMeta):
    @abstractmethod
    def hi(self):
        raise NotImplementedError("HH")

class Base3(object):
    __metaclass__ = ABCMeta
    @abstractmethod
    def hi(self):
        raise NotImplementedError("HH")

abc Module

  • ABCMeta
    • This should be the meta class of any class that wants to be the abc.
  • ABC
    • Just a simple wrapper, its meta class = ABCMeta. Users can directly inherit from it.
  • ABCMeta.register
    • Dynamically register any class and issubclass, isinstance will return True after registration.
    • Will not affect the MRO mechanism
  • abstractmethod:
    • If working with other decorators, please make sure that this is the first one. For example working with property or classmethod

collections.abc Module

Reference

ClassInherits fromRequired methodsMixin methods
Sized __len__ 
Awaitable __await__ 
CoroutineAwaitablesend;throwclose
AsyncIterable __aiter__ 
AsyncIteratorAsyncIterable__anext____aiter__
ASyncGeneratorAsyncIteratorasend, athrowaclose
Iterable __iter__ 
Callable __call__ 
Hashable __hash__ 
ReversableIterable__reversed__ 
IteratorIterable__next____iter__
GeneratorIteratorsend, throwclose, __iter__, __next__
Container __contains__ 
MutableSequence   
CollectionContainer
Iterable
Sized
__contains__
__iter__
__len__
 
SequenceReversable
Collection
__getitem__;__len____contains__;__iter__
__reversed__;index;count
MutableSequenceSequence__getitem__;__setitem__
__delitem__;__len__;insert
Inherited from Sequence,append
reverse,extend, pop, remove, __iadd__
ByteStringSequence__getitem__, __len__Inherit from Sequence
SetCollection__contains__
__iter__,__len__
__le__, __lt__, __eq__, __ne__, __gt__, __ge__
__and__, __or__, __xor__, __sub__, isdisjoint
MutableSetSet__contains__
__iter__, __len__, add, discard
Inhert from Set, clear, pop
remove
__ior__, __iand__, __ixor__, __isub__
MappingCollection__getitem__, __iter__, __len____contains__, keys, items, values
get, __eq__, __ne__
MutableMappingMapping__getitem__, __setitem__
__delitem__
__iter__, __len__
pop, popitem
clear, update, setdefault

*View related base classes are ommited.

Animal example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from abc import ABC, abstractmethod

class Animal(ABC):

    @abstractmethod
    def talk(self):
        pass

class Dog(Animal):

    def talk(self):
        print("Wang!")

class Cat(Animal):

    def talk(self):
        print("Meow!")


class Snake(object):

    def x(self):
        print("x")

Animal.register(Snake)

class Bird(Animal):
    pass

Dog().talk()
Cat().talk()
print(issubclass(Snake, Animal)) # True
print(isinstance(Snake(), Animal)) # True
# TypeError: Can't instantiate abstract class Bird with abstract methods talk
bird = Bird()

AwesomeSequence

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from collections.abc import Iterable

class AwesomeSequence(Iterable, Callable):

    def __init__(self):
        self._a = 1
        self._b = 0
        self._c = 2
        self._d = 4

    def __iter__(self):
        yield self._a
        yield self._b
        yield self._c
        yield self._d

    def __call__(self):
        return iter(self)

c = AwesomeSequence()
for v in iter(c):
    print(v)

for v in c():
    print(v)

This post is licensed under CC BY 4.0 by the author.