Создание абстрактных методов в Python: наследование и подклассы
Быстрый ответ
Абстрактные методы позволяют стандартизировать интерфейс. Они выставляют условия для реализации определённых методов в дочерних классах. Для этого используется модуль abc и декоратор @abstractmethod. Если попытаться создать объект класса, в котором не переопределены абстрактные методы, возникнет ошибка. Пример использования может выглядеть так:
from abc import ABC, abstractmethod
class MyBase(ABC):
@abstractmethod
def my_method(self):
pass
class MySubclass(MyBase):
def my_method(self):
return "Реализовано!"
При попытке создания инстанции MyBase появится ошибка TypeError, так как my_method не реализован.

Реализация абстрактных методов
Для определения абстрактных методов в классе необходимо использовать abc.ABC или metaclass=ABCMeta в объявлении базового класса.
Возможные ошибки при использовании abc
В процессе работы с модулем abc часто встречаются различные ошибки. Например:
- Отсутствие импорта
abstractmethod. - Неиспользование
ABCилиmetaclass=ABCMetaв базовом классе. - Некорректное переопределение абстрактного метода.
Продвинутое использование ABC
Применение ABCMeta в связке с другими метаклассами позволяет создавать сложные иерархии классов.
class MetaClassOne(type): pass
class MetaClassTwo(ABCMeta, MetaClassOne): pass
class ComplexBase(metaclass=MetaClassTwo):
@abstractmethod
def a_complex_method(self):
pass
Визуализация
Показательный пример использования abc.
class Instrument(metaclass=abc.ABCMeta):
@abstractmethod
def play(self):
pass
Абстрактный метод play будет определён в подклассах.
class Violin(Instrument):
def play(self):
pass # Здесь будет "Времена года" Вивальди
class Trumpet(Instrument):
def play(self):
pass # Здесь будет джаз Майлза Дэвиса
Альтернативы абстрактным базовым классам
В устаревших проектах часто используется исключение NotImplementedError там, где отсутствует реализация, однако это ограничивает возможности ABC.
class LegacyBase:
def my_legacy_method(self):
raise NotImplementedError("You must implement my_legacy_method.")
Реализация абстрактных методов: Python vs Java
В Python абстрактные методы могут включать в себя реализацию. Для вызова родительской версии достаточно использовать super().method_name.
class MyFlexibleBase(ABC):
@abstractmethod
def flexible_method(self):
print("Это реализация в базовом классе.")
class MyFlexibleSubclass(MyFlexibleBase):
def flexible_method(self):
super().flexible_method()
print("Это дополнение в классе-потомке.")
Абстрактные базовые классы, утиноподобная типизация и динамические проверки
Применение ABC сочетает строгость статической типизации и гибкость утиноподобной типизации Python. Классы, которые не отвечают условиям ABC, становятся очевидными.
Осуществление динамических проверок
Python использует исключения AttributeError и TypeError для динамической проверки наличия атрибутов и методов во время выполнения программы.


