Перечисления (Enum) в Python
Ключевые тезисы:
- Перечисления — это специальные классы для создания наборов неизменяемых констант
- Атрибуты перечисления — это объекты класса, а не просто значения
- Каждый атрибут имеет свойства
name(имя) иvalue(значение) - Перечисления повышают читаемость кода и предотвращают случайные изменения констант
Что такое перечисления
Перечисления — это наборы логически связанных констант, сгруппированные в одном классе. Например, цвета (красный, зелёный, синий) или геометрические фигуры (прямоугольник, треугольник, круг).
Проблема обычных классов
Обычный класс позволяет менять значения атрибутов, что нежелательно для констант:
class Color:
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
Color.green = 0 #
Изменение прошло без ошибок
Создание перечисления с помощью Enum
Импорт и наследование
from enum import Enum
class Color(Enum):
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
Защита от изменений
После наследования от Enum:
- Атрибуты становятся неизменяемыми
- Попытка изменить значение вызывает ошибку
- Можно только читать значения
Color.green = 0 #
AttributeError
value = Color.red #
Работает
Свойства объектов перечисления
Каждый атрибут перечисления — это объект класса с двумя встроенными свойствами:
| Свойство | Описание | Пример |
|---|---|---|
| name | Имя атрибута | Color.blue.name → 'blue' |
| value | Значение атрибута | Color.blue.value → (0, 0, 255) |
Итерация по перечислению
for color in Color:
print(f"{color.name} = {color.value}")
Результат:
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
Типы значений в перечислении
Значениями атрибутов могут быть любые типы данных:
class Mixed(Enum):
text = "строка"
number = 42
sequence = [1, 2, 3]
Важно: Используйте неизменяемые типы (кортежи, строки, числа), так как изменяемые объекты (списки, словари) могут быть модифицированы:
Color.black.value[0] = 10 #
Список изменился!
Доступ к атрибутам перечисления
Через точку
color = Color.red
По ключу (индексу)
color = Color['red']
Оба способа эквивалентны.
Псевдонимы (Aliases)
Если два атрибута имеют одинаковые значения, второй становится псевдонимом первого:
class Color(Enum):
white = 255
black = 255 # Это псевдоним white, не отдельный объект
При итерации black не отображается, но остаётся доступным:
Color.black # → Color.white (ссылается на тот же объект)
Декоратор @unique для уникальных значений
Если нужны только уникальные значения, используйте декоратор:
from enum import Enum, unique
@unique
class Color(Enum):
red = (255, 0, 0)
white = 255
black = 255 #
ValueError: duplicate values found
Практический пример: функция с перечислением
class Figure(Enum):
rect = 0
triangle = 1
circle = 2
def calc_perimeter(fig, *args):
if fig == Figure.rect:
return 2 * (args[0] + args[1])
elif fig == Figure.triangle:
return sum(args[:3])
elif fig == Figure.circle:
return 2 * 3.14 * args[0]
return -1
# Использование
print(calc_perimeter(Figure.rect, 10, 20)) # 60
print(calc_perimeter(Figure.triangle, 3, 4, 5)) # 12
print(calc_perimeter(Figure.circle, 5)) # 31.4
Преимущества перечисления в коде
Читаемость: Figure.rect понятнее, чем 0
Безопасность: Невозможно передать неправильное значение
Поддерживаемость: Код самодокументируется
Сравнение объектов перечисления
Разные классы перечисления
class Color(Enum):
red = (255, 0, 0)
class ColorRGB(Enum):
red = (255, 0, 0)
p1 = Color.red
p2 = ColorRGB.red
p1 == p2 #
False (разные классы)
Сравнение с числовыми значениями
Color.red == (255, 0, 0) #
False (объект ≠ значение)
Color.red.value == (255, 0, 0) #
True (сравнение значений)
Сравнение объектов одного класса
p1 = Color.red
p2 = Color.red
p1 == p2 #
True (один и тот же объект)
p1 is p2 #
True
Методы в перечислении
Перечисления могут содержать методы, как обычные классы:
class Figure(Enum):
rect = 0
triangle = 1
circle = 2
def describe(self):
if self == Figure.rect:
return "Прямоугольник"
elif self == Figure.triangle:
return "Треугольник"
elif self == Figure.circle:
return "Круг"
# Использование
fig = Figure.triangle
print(fig.describe()) # Треугольник
Выводы
Перечисления используются для:
- Создания наборов связанных констант
- Повышения читаемости и безопасности кода
- Предотвращения случайных изменений значений
Особенности:
- Атрибуты — это объекты, а не просто значения
- Каждый объект имеет
nameиvalue - Поддерживают итерацию и методы
- Сравнение работает между объектами одного класса