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,isinstancewill returnTrueafter 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
propertyorclassmethod
- 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)