Python 3.8+Annotations & typingterm
typing.Protocol
protocol
Defines an interface by structure (duck typing). A class is compatible if it implements every method of the Protocol, with no explicit inheritance.
Syntax
from typing import Protocol
class MyProtocol(Protocol):
def method(self) -> type: ...
Protocol earns its keep when you need to type third-party classes you cannot make inherit from an ABC: compatibility comes from the set of methods, not from ancestry. By default it is a purely static affair — isinstance against a protocol raises TypeError until the protocol is decorated with @runtime_checkable, and even then only the presence of the attributes is checked, never their signatures.
Examples
from typing import Protocol
class Drawable(Protocol):
def draw(self) -> None: ...
class Circle:
def draw(self) -> None: print('O')
class Square:
def draw(self) -> None: print('[]')
def render(shape: Drawable) -> None:
shape.draw()
render(Circle()) # → O
render(Square()) # → []
from typing import Protocol, runtime_checkable
@runtime_checkable
class Drawable(Protocol):
def draw(self) -> None: ...
class Circle:
def draw(self) -> None: print('O')
print(isinstance(Circle(), Drawable)) # → True — наследовать не нужно
print(isinstance(42, Drawable)) # → False
See also
Open in the full glossarydocs.python.orgReport an inaccuracy