Ответ
Ключевое различие заключается в подходе к определению соответствия интерфейсу: ABC использует номинальную типизацию (явное наследование), а Protocol — структурную типизацию (утиную типизацию).
1. Интерфейс на основе abc.ABC (номинальная типизация)
Класс должен явно наследоваться от абстрактного базового класса (ABC) и реализовывать все его абстрактные методы, помеченные декоратором @abstractmethod. Соответствие проверяется во время выполнения (runtime).
Пример:
from abc import ABC, abstractmethod
class Serializable(ABC):
@abstractmethod
def serialize(self) -> bytes:
pass
# Класс User ДОЛЖЕН наследоваться от Serializable
class User(Serializable):
def serialize(self) -> bytes:
return b'user_data'
# Этот код вызовет TypeError, т.к. метод не реализован
# class Product(Serializable):
# pass
# p = Product()
2. Интерфейс на основе typing.Protocol (структурная типизация)
Классу не нужно наследоваться от протокола. Он считается совместимым, если имеет все методы и атрибуты, определённые в протоколе, с правильными сигнатурами. Проверка в основном выполняется статическими анализаторами кода (Mypy, Pyright).
Пример:
from typing import Protocol
class Serializable(Protocol):
def serialize(self) -> bytes:
...
# Класс User НЕ наследуется от Serializable, но соответствует протоколу
class User:
def serialize(self) -> bytes:
return b'user_data'
# Статический анализатор проверит, что obj имеет метод .serialize()
def save(obj: Serializable):
data = obj.serialize()
print(f"Saving {len(data)} bytes")
save(User()) # Ошибок нет
Итог
| Критерий | abc.ABC |
typing.Protocol |
|---|---|---|
| Типизация | Номинальная | Структурная |
| Наследование | Обязательно | Не требуется |
| Проверка | Runtime | Static (Mypy) |
| Гибкость | Низкая | Высокая (можно "адаптировать" сторонние классы) |
Ответ 18+ 🔞
А, слушай, вот тут тема интересная, блядь! Про то, как в Питоне интерфейсы делать. Так вот, есть два главных подхода, и разница между ними — это просто пиздец, нахуй, принципиальная. Один — это как официальная бумажка с печатью, а другой — как «ну ты ж понимаешь, ты же можешь».
Первый — это abc.ABC. Это, сука, номинальная типизация. То есть, чтобы считаться своим, ты должен явно нахуяриться от этого самого ABC и все его абстрактные методы реализовать. Иначе — пиздец, тебя на этапе создания объекта размажут по стенке с TypeError. Это как прийти на завод и сказать: «Я токарь». А тебе: «Ну покажи диплом, блядь!». Нет диплома — иди нахуй.
from abc import ABC, abstractmethod
class Serializable(ABC):
@abstractmethod
def serialize(self) -> bytes:
pass
# Класс User ДОЛЖЕН наследоваться от Serializable
class User(Serializable):
def serialize(self) -> bytes:
return b'user_data'
# А вот этот уёбок не реализовал метод — получи пизды сразу!
# class Product(Serializable):
# pass
# p = Product() # Тут тебе и выедет: TypeError, мудак!
Второй — это typing.Protocol. Вот это, ёпта, уже структурная типизация, или, как её ещё обзывают, утиная. Суть проста: если что-то ходит как утка и крякает как утка, то похуй, что у него в паспорте написано «бобёр». Главное — методы есть. Наследоваться не надо, главное — структура совпадает. Проверяют это в основном всякие статические анализаторы вроде Mypy, они умные, они видят.
from typing import Protocol
class Serializable(Protocol):
def serialize(self) -> bytes:
...
# Смотри, какая хуйня! Класс User НЕ наследуется от протокола!
class User:
def serialize(self) -> bytes:
return b'user_data'
# Но функция-то ждёт объект, который умеет .serialize()
def save(obj: Serializable):
data = obj.serialize()
print(f"Saving {len(data)} bytes")
save(User()) # И тут всё заебись! Mypy не орёт, runtime не падает. Магия, блядь!
Короче, итоговая таблица, чтобы в голове не ебалось:
| Критерий | abc.ABC |
typing.Protocol |
|---|---|---|
| Типизация | Номинальная (диплом нужен) | Структурная (главное — уметь) |
| Наследование | Обязательно, блядь! | Похуй, можно без него |
| Кто проверяет | Runtime (интерпретатор, строгий, как тёща) | Статический анализатор (Mypy, умный дядька) |
| Гибкость | Низкая, жёсткая | Высокая, овердохуищная (можно даже со сторонними библиотеками работать) |
Так что выбирай, что тебе ближе: официальная бумажка с печатью или «и так сойдёт, главное — работает».