← Назад к вопросам
Как реализовать интерфейс?
1.0 Junior🔥 241 комментариев
#Python Core#Архитектура и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как реализовать интерфейс
В Python интерфейсы реализуются через абстрактные классы из модуля abc (Abstract Base Classes). Это позволяет определить контракт, который обязан выполнять любой класс, наследующий интерфейс.
Базовая реализация интерфейса
from abc import ABC, abstractmethod
# Определение интерфейса (абстрактного класса)
class PaymentProcessor(ABC):
"""Интерфейс для обработки платежей"""
@abstractmethod
def process_payment(self, amount: float) -> bool:
"""Обработать платёж"""
pass
@abstractmethod
def refund(self, transaction_id: str) -> bool:
"""Вернуть деньги"""
pass
# Реализация интерфейса
class CreditCardProcessor(PaymentProcessor):
"""Конкретная реализация для кредитных карт"""
def process_payment(self, amount: float) -> bool:
print(f"Обработка платежа {amount} через кредитную карту")
# Логика обработки платежа
return True
def refund(self, transaction_id: str) -> bool:
print(f"Возврат платежа {transaction_id}")
return True
# Использование
processor = CreditCardProcessor()
processor.process_payment(100.0) # Обработка платежа 100.0 через кредитную карту
# Попытка создать экземпляр интерфейса — ошибка
# payment = PaymentProcessor() # TypeError: Can't instantiate abstract class
Ошибка при неполной реализации
class IncompleteProcessor(PaymentProcessor):
"""Неполная реализация интерфейса"""
def process_payment(self, amount: float) -> bool:
return True
# refund не реализован!
# Это вызовет ошибку
processor = IncompleteProcessor()
# TypeError: Can't instantiate abstract class IncompleteProcessor with abstract methods refund
Абстрактные методы с телом (поведение по умолчанию)
from abc import ABC, abstractmethod
class DatabaseConnection(ABC):
"""Интерфейс для подключения к БД"""
@abstractmethod
def connect(self) -> bool:
"""Установить соединение"""
# Может быть тело метода с логикой по умолчанию
print("Инициализация соединения")
@abstractmethod
def execute(self, query: str) -> list:
"""Выполнить запрос"""
pass
def close(self):
"""Закрыть соединение (не абстрактный)"""
print("Соединение закрыто")
class PostgreSQLConnection(DatabaseConnection):
def connect(self) -> bool:
super().connect() # Вызовем поведение по умолчанию
print("PostgreSQL соединение установлено")
return True
def execute(self, query: str) -> list:
print(f"Выполняю SQL: {query}")
return []
db = PostgreSQLConnection()
db.connect() # Инициализация соединения\nPostgreSQL соединение установлено
Абстрактные свойства (properties)
from abc import ABC, abstractmethod
class Animal(ABC):
"""Интерфейс для животного"""
@property
@abstractmethod
def name(self) -> str:
"""Имя животного"""
pass
@property
@abstractmethod
def species(self) -> str:
"""Вид животного"""
pass
@abstractmethod
def make_sound(self) -> str:
pass
class Dog(Animal):
def __init__(self, dog_name: str):
self._name = dog_name
@property
def name(self) -> str:
return self._name
@property
def species(self) -> str:
return "Canine"
def make_sound(self) -> str:
return "Woof!"
dog = Dog("Buddy")
print(dog.name) # Buddy
print(dog.species) # Canine
print(dog.make_sound()) # Woof!
Интерфейсы с типами данных
from abc import ABC, abstractmethod
from typing import Generic, TypeVar, List
T = TypeVar('T')
class Repository(ABC, Generic[T]):
"""Интерфейс для работы с репозиториями"""
@abstractmethod
def get_by_id(self, id: int) -> T | None:
pass
@abstractmethod
def get_all(self) -> List[T]:
pass
@abstractmethod
def save(self, entity: T) -> T:
pass
@abstractmethod
def delete(self, id: int) -> bool:
pass
class User:
def __init__(self, id: int, name: str):
self.id = id
self.name = name
class UserRepository(Repository[User]):
def __init__(self):
self.users: dict[int, User] = {}
def get_by_id(self, id: int) -> User | None:
return self.users.get(id)
def get_all(self) -> List[User]:
return list(self.users.values())
def save(self, entity: User) -> User:
self.users[entity.id] = entity
return entity
def delete(self, id: int) -> bool:
if id in self.users:
del self.users[id]
return True
return False
# Использование
repo = UserRepository()
user = User(1, "Alice")
repo.save(user)
print(repo.get_by_id(1).name) # Alice
Множественная реализация (миксины)
from abc import ABC, abstractmethod
class Serializable(ABC):
@abstractmethod
def to_dict(self) -> dict:
pass
class Comparable(ABC):
@abstractmethod
def __eq__(self, other) -> bool:
pass
class Product(Serializable, Comparable):
def __init__(self, id: int, name: str):
self.id = id
self.name = name
def to_dict(self) -> dict:
return {"id": self.id, "name": self.name}
def __eq__(self, other) -> bool:
return isinstance(other, Product) and self.id == other.id
product = Product(1, "Laptop")
print(product.to_dict()) # {'id': 1, 'name': 'Laptop'}
print(product == Product(1, "Phone")) # True (одинаковые ID)
Проверка реализации интерфейса (isinstance)
from abc import ABC, abstractmethod
class DataSource(ABC):
@abstractmethod
def fetch(self):
pass
class APIDataSource(DataSource):
def fetch(self):
return {"data": "from API"}
api = APIDataSource()
print(isinstance(api, DataSource)) # True
# Проверка всех абстрактных методов
print(hasattr(api, 'fetch')) # True
Реальный пример: система уведомлений
from abc import ABC, abstractmethod
from typing import List
class Notifier(ABC):
"""Интерфейс для отправки уведомлений"""
@abstractmethod
def send(self, recipient: str, message: str) -> bool:
pass
class EmailNotifier(Notifier):
def send(self, recipient: str, message: str) -> bool:
print(f"Email отправлено на {recipient}: {message}")
return True
class SMSNotifier(Notifier):
def send(self, recipient: str, message: str) -> bool:
print(f"SMS отправлено на {recipient}: {message}")
return True
class PushNotifier(Notifier):
def send(self, recipient: str, message: str) -> bool:
print(f"Push отправлено пользователю {recipient}: {message}")
return True
class NotificationManager:
def __init__(self, notifiers: List[Notifier]):
self.notifiers = notifiers
def notify_all(self, recipient: str, message: str):
for notifier in self.notifiers:
notifier.send(recipient, message)
# Использование
manager = NotificationManager([
EmailNotifier(),
SMSNotifier(),
PushNotifier()
])
manager.notify_all("user@example.com", "Важное сообщение")
Вывод: интерфейс в Python — это абстрактный класс с @abstractmethod, который определяет контракт для реализующих его классов. Это обеспечивает полиморфизм и делает код более гибким и тестируемым.