Sobes.tech
Back to questions
Junior — Middle
62

Объясните отличия между использованием абстрактных классов и протоколов в Python для определения интерфейсов.

Answer from AI

sobes.tech AI

В Python для определения интерфейсов можно использовать абстрактные классы (ABC) и протоколы (Protocol).

Абстрактные классы (ABC)

  • Определяются с помощью модуля abc и декоратора @abstractmethod.
  • Могут содержать как абстрактные методы, так и реализованные методы.
  • Требуют, чтобы подклассы явно наследовали от абстрактного класса и реализовали все абстрактные методы.
  • Используются для строгого контроля иерархии классов.

Протоколы (Protocol)

  • Введены в модуле typing (начиная с Python 3.8).
  • Определяют интерфейс, который класс должен поддерживать, но не требуют явного наследования.
  • Поддерживают структурную типизацию (duck typing): если объект имеет нужные методы и атрибуты, он считается соответствующим протоколу.
  • Удобны для гибкой типизации и проверки типов в статических анализаторах.

Кратко:

  • Абстрактные классы — это номинальный тип интерфейса, требующий наследования.
  • Протоколы — структурный тип интерфейса, основанный на наличии методов, без необходимости наследования.

Пример абстрактного класса:

from abc import ABC, abstractmethod

class MyInterface(ABC):
    @abstractmethod
    def do_something(self):
        pass

class Implementation(MyInterface):
    def do_something(self):
        print("Doing something")

Пример протокола:

from typing import Protocol

class MyProtocol(Protocol):
    def do_something(self) -> None:
        ...

class Implementation:
    def do_something(self) -> None:
        print("Doing something")


def func(obj: MyProtocol):
    obj.do_something()

impl = Implementation()
func(impl)  # Работает, хотя Implementation не наследует MyProtocol