В Python, помимо стандартных типов данных, существует еще один интересный инструмент для работы с типами - типы протоколов. Они используют structural typing, что означает, что проверка типов происходит по структуре объекта, а не по его имени. Это означает, что объект будет считаться соответствующим протоколу, если он имеет все необходимые методы и атрибуты, даже если он не наследует от протокола явно.
Типы протоколов позволяют определять интерфейсы для классов, не требуя явного наследования. Это может быть полезно, когда вы работаете с классами, которые не находятся под вашим контролем, или когда вы хотите создать более гибкую систему типизации.
Рассмотрим пример:
from typing import Protocol
class Printable(Protocol):
def print_something(self, message: str) -> None:
...
def process_printable(obj: Printable) -> None:
obj.print_something("Hello, world!")
class MyClass:
def print_something(self, message: str) -> None:
print(f"MyClass says: {message}")
my_object = MyClass()
process_printable(my_object)
В этом примере мы определяем протокол Printable
, который требует, чтобы объекты, которые его реализуют, имели метод print_something()
. Затем мы определяем функцию process_printable()
, которая принимает объект, реализующий протокол Printable
, и вызывает его метод print_something()
.
Обратите внимание, что MyClass
не наследует от Printable, но все равно может быть использована в process_printable()
, потому что она реализует необходимый интерфейс.
Important
Типы протоколов позволяют определять интерфейсы для классов без явного наследования, что делает ваш код более гибким и расширяемым.