Contents
Python interfaces
See Real Python
Informal interfaces
- define a base class with ‘abstract" methods (e.g. throwing NotImplementedError)
- Subclass by implementations
- Pb :
issubclass(<subclass>, <baseclass>)
is always true even when the subclass doesn’t fully implement the interface <subclass>.__mro__
shows the interface even when its not implemented- NB : when raising NotImplementedError, pycharm warns in the subclass but mypy doesn’t
Using Metaclasses
Check this great article
- Implementing 2 dunder methods :
__instancecheck__()
and__subclasscheck__()

- By using a metaclass, you don’t need to explicitly define the subclasses. Instead, the subclass must define the required methods. If it doesn’t, then
issubclass(EmlParserNew, UpdatedInformalParserInterface)
will returnFalse
- As you can see,
UpdatedInformalParserInterface
is a superclass ofPdfParserNew
, but it doesn’t appear in the MRO. This unusual behavior is caused by the fact thatUpdatedInformalParserInterface
is a virtual base class ofPdfParserNew
.
Virtual base classes
-
When a class builds from a metaclass it will be a virtual base class of any class implementing the metaclass
-
A class building from a metaclass can be called an interface
-
We have
-
isinstance(Interface, Metaclass) == True
if interface builds from the metaclass -
issubclass(ConcreteClass, Interface) == True
if ConcreteClass implements Interface -
isinstance(ConcreteClass(), Interface) == True
-

Metaclasses usage
- See stack
- Registering each subclass in a data structure
- Allow changing the evaluation of class body
- Allow creating overloaded methods
Formal Interfaces
Using abc.ABCMeta
- like creating a custom metaclass but more standard

Using abc
to Register a Virtual Subclass
- Once you’ve imported the
abc
module, you can directly register a virtual subclass by using the.register()
metamethod - NB : allows creating metaclass of literal types for example
- Once you’ve registered
Double
, you can use it as class decorator to set the decorated class as a virtual subclass. NB : can be dangerous __subclasshook__
takes precedence over register
Using Abstract Method Declaration
Mypy Protocols
- Mypy supports two ways of deciding whether two classes are compatible as types: nominal subtyping and structural subtyping
- Nominal subtyping = normal inheritance, compatible with instance of
- Structural subtyping :
- Class
D
is a structural subtype of classC
if the former has all attributes and methods of the latter, and with compatible types - Structural subtyping can be seen as a static equivalent of duck typing
- Class
Existing protocols
- Iteration protocols: Iterable[T] and Iterator[T]
- Collection protocols: Sized, Container[T], Collection[T]
- etc.. (One-off protocols, Async Protocols, Context manager protocols ..)
User defined protocols
- Note that inheriting from an existing protocol does not automatically turn the subclass into a protocol – it just creates a regular (non-protocol) class or ABC that implements the given protocol (or protocols). The
Protocol
base class must always be explicitly present if you are defining a protocol
Interface libraries
zope.interface
[zope-interfaces] was one of the first widely used approaches to structural subtyping in Python- Design by contract, supports invariants
