Ответ
Программный контракт — это формальное соглашение об интерфейсе между компонентами системы (например, модулями, классами или функциями). Он определяет взаимные обязательства: что компонент ожидает на входе и что гарантирует на выходе.
Контракт обычно определяет:
- Предусловия (Preconditions): Условия, которые должны быть истинны перед вызовом функции (например, типы и значения аргументов).
- Постусловия (Postconditions): Условия, которые должны быть истинны после завершения работы функции (например, тип и свойства возвращаемого значения).
- Инварианты (Invariants): Условия, которые остаются неизменными для объекта на протяжении его жизненного цикла.
Способы реализации в Python:
- Аннотации типов (Type Hints): Основной способ определения контракта по типам данных.
- Докстринги (Docstrings): Словесное описание логики, аргументов, возвращаемых значений и возможных исключений.
- Утверждения (Assertions): Проверки условий (
assert
), которые активны в режиме разработки и отключаются в продакшене. - Абстрактные базовые классы (ABC): Для определения интерфейсов, которые должны реализовывать дочерние классы.
Пример функции с контрактом:
from typing import List
def calculate_average(numbers: List[float]) -> float:
"""
Вычисляет среднее значение для списка чисел.
Args:
numbers: Список чисел для вычисления среднего.
Returns:
Среднее арифметическое значение.
Raises:
ValueError: Если список пуст.
"""
# Предусловие: список не должен быть пустым
if not numbers:
raise ValueError("Список для вычисления среднего не может быть пустым")
result = sum(numbers) / len(numbers)
# Постусловие (неявное): результат является float
return result
# Корректное использование
print(calculate_average([1.0, 2.0, 3.0, 6.0])) # Вывод: 3.0
# Нарушение контракта
# calculate_average([]) # Вызовет ValueError
Соблюдение контрактов делает код более надежным, предсказуемым и легким для отладки.