Types
Protocols
A protocol names required behavior. The ellipsis marks the method body as intentionally unspecified, similar to an interface declaration.
Source
from typing import Protocol
class Greeter(Protocol):
def greet(self) -> str:
...
print(Greeter.__name__)Output
GreeterA class can satisfy the protocol without inheriting from it. Person has a compatible greet() method, so it has the right shape for static type checkers.
Source
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"hello {self.name}"
print(Person("Ada").greet())Output
hello AdaUse the protocol as an annotation at the API boundary. The function only cares that the object can greet; it does not care about the concrete class.
Source
def welcome(greeter: Greeter):
print(greeter.greet())
welcome(Person("Ada"))Output
hello AdaNotes
- Protocols are for structural typing: compatibility by shape rather than explicit inheritance.
- Type checkers understand protocols; normal runtime method calls still do the work.
- Prefer inheritance when shared implementation matters, and protocols when only required behavior matters.
See also
- related: Type Hints
- prerequisite: Classes
- prerequisite: Inheritance and Super
- next depth: Abstract Base Classes
Run the complete example
Expected output
hello Ada
Greeter
Execution time appears here after you run the example.