Say I have some code where I expect a class possessing some characteristics like attributes or methods, but I don't want to use inheritance to enforce this, preferring composition instead.
How would I go about enforcing that the class/object received as argument actually presents these characteristics?
Example with inheritance:
from abc import ABC, abstractmethod
class FooBase(ABC):
@abstractmethod
def do_stuff(self):
pass
class Foo(FooBase):
def do_stuff(self):
return 'hello'
def some_function(obj: FooBase):
print(obj.do_stuff())
In this above example, some_function is enforcing (statically through MyPy) that the obj parameter is a subclass of FooBase.
Instead, I'd like that some_function enforces (statically, via MyPy) that obj has a do_stuff method, without it necessarily being a subclass of FooBase.
Use
typing.Protocol:The difference between a
Protocoland anABCis that you can implement a protocol without explicitly inheriting from it, soBaris considered aFooby mypy even though it's not a subclass ofFoo.If you pass a type that doesn't implement the protocol, you get an error, e.g.: