Освой Python играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Python: Enum (Перечисления)

Python поддерживает перечисления. Нужно объявить класс, наследованный от Enum. Далее описываются все нужные значения через понятные имена. Мы можем получить значение через value, а имя через name.

Перечисления полезны, когда вы хотите иметь некоторые текстовые идентификаторы для констант. Такой подход повышает читабельность.


from enum import Enum

class CatColor(Enum):
  WHITE = 0
  BLACK = 1
  GINGER = 2
  
cat = CatColor.GINGER

# Выводит 2
print(cat.value)

# Выводит GINGER (Рыжий)
print(cat.name)

# Выводит следующее: <CatColor.GINGER: 2>
print(repr(cat)) 

Проверить тип перечисления можно через type().


print(type(CatColor.BLACK)) # <enum 'CatColor'>

Убедиться, что выбранный элемент перечисления относится к перечислению, можно через isinstance().


print(isinstance(cat, CatColor)) # True

Пройтись по всем элементам перечисления можно в цикле.


for color in CatColor:
    print(color)
	
# Результат
CatColor.WHITE
CatColor.BLACK
CatColor.GINGER

Получить список элементов можно через list().


print(list(CatColor))

Программно можно обратиться как по значению, так и по имени.


print(CatColor(1))       # CatColor.BLACK
print(CatColor['WHITE']) # CatColor.WHITE

Нельзя дублировать имена перечислений, иначе получим ошибку. А значения могут совпадать, тогда будет считаться, что мы создали псевдоним.


from enum import Enum

class Shape(Enum):
  SQUARE = 0
  DIAMOND = 1
  CIRCLE = 2
  POINT = 0
  
print(Shape.SQUARE) # Shape.SQUARE
print(Shape.POINT)  # Shape.SQUARE

Если мы не хотим иметь дубликатов значений, то можно добавить аннотацию @unique. В этом случае при компиляции мы получим ошибку ValueError при дублировании значений в перечислении. Перепишем пример.


from enum import Enum, unique

@unique
class Shape(Enum):
  SQUARE = 0
  DIAMOND = 1
  CIRCLE = 2
  POINT = 0
  
print(Shape.SQUARE)
print(Shape.POINT)

# ValueError: duplicate values found in <enum 'Shape'>: POINT -> SQUARE

Также существуют похожие классы IntEnum, IntFlag, Flag.

Дополнительные материалы

Страница документации по Enum

Реклама