Найти тему
С любовью о Python

Автоматическое присваивание значений в Enum

Оглавление

Представим ситуацию: вы любите все структурировать и храните много данных в енамах: Enum, StrEnum, IntEnum и так далее.

В какой-то момент обязательно накопится большое количество структур, где символическое имя будет равно значению, как в примере ниже:

-2

Как красиво выйти из этой ситуации? Об этом мы и поговорим.

Функция auto()

В первую очередь, стоит обратить внимание на класс auto из Enum.

Он позволяет нам автоматически присваивать значения для каждого символического имени, мы можем просто указать его в виде значений:

-3

Как это работает

Класс auto автоматически присваивает значение для символического имени в виде номера по порядку.
Например, для блока кода выше будут присвоены значения
HAPPY = 1, SAD = 2:

-4

Когда это может пригодиться?

Например, когда мы перебираем Enum-ы через match-case и значения нам не важны.

А если важны?

Что делать, если в value нужно хранить именно символическое имя?

Представим ситуацию, когда нам очень нужно, чтобы name было равно value, и чтоб это value присваивалось автоматически.

Здесь нам на помощь придет переопределение метода _generate_next_value_.

Синтаксис

_generate_next_value_(name, start, count, last_values)
Этот метод и отвечает за увеличение значения символического имени на 1 в исходной реализации, но мы можем подстроить его под себя.

Это можно сделать прямо внутри нужного нам Enum-а:

-5

главное, переопределить метод перед членами Enum-а, иначе словим исключение TypeError.

И тогда при выводе значений в терминал мы получим уже имена членов Enum, а не индексы:

-6

Если ситуация часто повторяется, то можно сделать одно общее решение для всех. Создадим класс AutoName, унаследованный от Enum и переопределим метод _generate_next_value_:

-7

Нам остается отнаследоваться от этого класса и использовать auto() в качестве значений символических имен Enum-а:

-8

Убедимся, что наша шалость удалась:

-9

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

***

Присоединяйтесь ко мне в Telegram: https://t.me/python3_with_love. Там есть все, и читать код намного удобнее.