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.
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.
- Just a simple wrapper, its meta class =
ABCMeta.register
- Dynamically register any class and
issubclass
,isinstance
will returnTrue
after registration. - Will not affect the MRO mechanism
- Dynamically register any class and
abstractmethod
:- If working with other decorators, please make sure that this is the first one. For example
working with
property
orclassmethod
- If working with other decorators, please make sure that this is the first one. For example
working with
collections.abc
Module
Class | Inherits from | Required methods | Mixin methods |
---|---|---|---|
Sized | __len__ | ||
Awaitable | __await__ | ||
Coroutine | Awaitable | send;throw | close |
AsyncIterable | __aiter__ | ||
AsyncIterator | AsyncIterable | __anext__ | __aiter__ |
ASyncGenerator | AsyncIterator | asend, athrow | aclose |
Iterable | __iter__ | ||
Callable | __call__ | ||
Hashable | __hash__ | ||
Reversable | Iterable | __reversed__ | |
Iterator | Iterable | __next__ | __iter__ |
Generator | Iterator | send, throw | close, __iter__, __next__ |
Container | __contains__ | ||
MutableSequence | |||
Collection | Container Iterable Sized |
__contains__ __iter__ __len__ |
|
Sequence | Reversable Collection |
__getitem__;__len__ | __contains__;__iter__ __reversed__;index;count |
MutableSequence | Sequence | __getitem__;__setitem__ __delitem__;__len__;insert |
Inherited from Sequence,append reverse,extend, pop, remove, __iadd__ |
ByteString | Sequence | __getitem__, __len__ | Inherit from Sequence |
Set | Collection | __contains__ __iter__,__len__ |
__le__, __lt__, __eq__, __ne__, __gt__, __ge__ __and__, __or__, __xor__, __sub__, isdisjoint |
MutableSet | Set | __contains__ __iter__, __len__, add, discard |
Inhert from Set, clear, pop remove __ior__, __iand__, __ixor__, __isub__ |
Mapping | Collection | __getitem__, __iter__, __len__ | __contains__, keys, items, values get, __eq__, __ne__ |
MutableMapping | Mapping | __getitem__, __setitem__ __delitem__ __iter__, __len__ |
pop, popitem clear, update, setdefault |
*View
related base classes are ommited.
Animal example
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
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)