Представим ситуацию: вы любите все структурировать и храните много данных в енамах: Enum, StrEnum, IntEnum и так далее.
В какой-то момент обязательно накопится большое количество структур, где символическое имя будет равно значению, как в примере ниже:
Как красиво выйти из этой ситуации? Об этом мы и поговорим.
Функция auto()
В первую очередь, стоит обратить внимание на класс auto из Enum.
Он позволяет нам автоматически присваивать значения для каждого символического имени, мы можем просто указать его в виде значений:
Как это работает
Класс auto автоматически присваивает значение для символического имени в виде номера по порядку.
Например, для блока кода выше будут присвоены значения HAPPY = 1, SAD = 2:
Когда это может пригодиться?
Например, когда мы перебираем Enum-ы через match-case и значения нам не важны.
А если важны?
Что делать, если в value нужно хранить именно символическое имя?
Представим ситуацию, когда нам очень нужно, чтобы name было равно value, и чтоб это value присваивалось автоматически.
Здесь нам на помощь придет переопределение метода _generate_next_value_.
Синтаксис
_generate_next_value_(name, start, count, last_values)
Этот метод и отвечает за увеличение значения символического имени на 1 в исходной реализации, но мы можем подстроить его под себя.
Это можно сделать прямо внутри нужного нам Enum-а:
главное, переопределить метод перед членами Enum-а, иначе словим исключение TypeError.
И тогда при выводе значений в терминал мы получим уже имена членов Enum, а не индексы:
Если ситуация часто повторяется, то можно сделать одно общее решение для всех. Создадим класс AutoName, унаследованный от Enum и переопределим метод _generate_next_value_:
Нам остается отнаследоваться от этого класса и использовать auto() в качестве значений символических имен Enum-а:
Убедимся, что наша шалость удалась:
Мы получили то, что нам было нужно, избавились от дублирования и лишней копипасты, сделав код еще немного чище.
***
Присоединяйтесь ко мне в Telegram: https://t.me/python3_with_love. Там есть все, и читать код намного удобнее.