Перечисления с помощью enum
Моделируйте фиксированный набор вариантов как именованные константы вместо разрозненных строк или чисел
enum) — это класс, экземпляры которого образуют фиксированный именованный набор константных значений: статусы заказа, роли пользователей, цвета светофора или масти карт. Вместо того чтобы разбрасывать по коду голые строки вроде "paid" или магические числа вроде 2, вы один раз определяете Status.PAID и позволяете Python гарантировать, что набор закрыт, самодокументирован и безопасен для сравнения.
- объяснить, почему голые строковые/числовые константы хрупки,
- определить перечисление с помощью
enum.Enumи читать у элемента.nameи.value, - безопасно сравнивать элементы через
isи понимать, почему элементы — синглтоны, - позволить Python присваивать значения автоматически с помощью
auto(), - использовать
IntEnum, когда элемент должен вести себя как целое число, - находить элемент по значению (
Color(1)) или по имени (Color['RED']) и перебирать весь набор.
1. Проблема голых констант
Фиксированные наборы вариантов встречаются повсюду: заказ бывает "pending", "paid" или "shipped"; пользователь — "admin" или "member". Наивный подход — писать эти значения прямо в коде как обычные строки или числа, так называемые магические значения.
status = "shiped" # опечатка! никто не жалуется до поры
if status == "shipped": # никогда не совпадёт -> тихая ошибка
send_tracking_email()
Ничто не ловит опечатку "shiped". Сравнение молча возвращает False, и письмо никогда не отправляется. У голых констант три слабости:
- Нет безопасности: любая строка с опечаткой — всё ещё допустимая строка, поэтому ошибки всплывают во время выполнения, а не при написании.
- Нет самодокументируемости: случайная
2вif role == 2:ничего не говорит читателю о том, что означает2. - Нет закрытого набора: ничто не мешает другой части программы придумать четвёртый неожиданный статус.
Перечисление устраняет всё сразу: имена проверяются, читаются как документация, а набор допустимых значений определён ровно в одном месте.