class abc.ABCMeta
Metaclass for defining Abstract Base Classes (ABCs).
Use this metaclass to create an ABC. An ABC can be subclassed directly, and then acts as a mix-in class. You can also register unrelated concrete classes (even built-in classes) and unrelated ABCs as “virtual subclasses” – these and their descendants will be considered subclasses of the registering ABC by the built-in issubclass() function, but the registering ABC won’t show up in their MRO (Method Resolution Order) nor will method implementations defined by the registering ABC be callable (not even via super()). [1]
Classes created with a metaclass of ABCMeta have the following method:
-
register(subclass) -
Register subclass as a “virtual subclass” of this ABC. For example:
from abc import ABCMeta class MyABC(metaclass=ABCMeta): pass MyABC.register(tuple) assert issubclass(tuple, MyABC) assert isinstance((), MyABC)Changed in version 3.3: Returns the registered subclass, to allow usage as a class decorator.
Changed in version 3.4: To detect calls to
register(), you can use theget_cache_token()function.
You can also override this method in an abstract base class:
-
__subclasshook__(subclass) -
(Must be defined as a class method.)
Check whether subclass is considered a subclass of this ABC. This means that you can customize the behavior of
issubclassfurther without the need to callregister()on every class you want to consider a subclass of the ABC. (This class method is called from the__subclasscheck__()method of the ABC.)This method should return
True,FalseorNotImplemented. If it returnsTrue, the subclass is considered a subclass of this ABC. If it returnsFalse, the subclass is not considered a subclass of this ABC, even if it would normally be one. If it returnsNotImplemented, the subclass check is continued with the usual mechanism.
For a demonstration of these concepts, look at this example ABC definition:
class Foo:
def __getitem__(self, index):
...
def __len__(self):
...
def get_iterator(self):
return iter(self)
class MyIterable(metaclass=ABCMeta):
@abstractmethod
def __iter__(self):
while False:
yield None
def get_iterator(self):
return self.__iter__()
@classmethod
def __subclasshook__(cls, C):
if cls is MyIterable:
if any("__iter__" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
MyIterable.register(Foo)
The ABC MyIterable defines the standard iterable method, __iter__(), as an abstract method. The implementation given here can still be called from subclasses. The get_iterator() method is also part of the MyIterable abstract base class, but it does not have to be overridden in non-abstract derived classes.
The __subclasshook__() class method defined here says that any class that has an __iter__() method in its __dict__ (or in that of one of its base classes, accessed via the __mro__ list) is considered a MyIterable too.
Finally, the last line makes Foo a virtual subclass of MyIterable, even though it does not define an __iter__() method (it uses the old-style iterable protocol, defined in terms of __len__() and __getitem__()). Note that this will not make get_iterator available as a method of Foo, so it is provided separately.
Please login to continue.