Сообщить об ошибке.

Функциональный синтаксис создания перечисления Enum

Класс enum.Enum обеспечивает следующий функциональный API при его вызове:

>>> from enum import Enum
>>> Animal = Enum('Animal', 'ANT BEE CAT DOG')
>>> Animal
# <enum 'Animal'>
>>> Animal.ANT
# <Animal.ANT: 1>
>>> Animal.ANT.value
# 1
>>> list(Animal)
# [<Animal.ANT: 1>, <Animal.BEE: 2>, <Animal.CAT: 3>, <Animal.DOG: 4>]

Семантика этого API напоминает collections.namedtuple. Первый аргумент вызова Enum - это имя перечисления.

Второй аргумент - это источник имен членов перечисления. Это может быть строка имен, разделенных пробелами, последовательность имен, последовательность двух кортежей с парами ключ/значение или отображение (например словарь) имен в значения.

Последние две опции позволяют назначать произвольные значения перечислениям. Другие - автоматически присваивают возрастающие целые числа, начиная с 1. Чтобы указать другое начальное значение, необходимо использовать параметр start. При этом возвращается новый класс, производный от Enum. Другими словами, указанное выше выражение Animal эквивалентно:

>>> class Animal(Enum):
...     ANT = 1
...     BEE = 2
...     CAT = 3
...     DOG = 4

Причина, по которой в качестве начального числа по умолчанию используется 1, а не 0, заключается в том, что 0 имеет значение False в логическом смысле, а все члены перечисления оцениваются как True.

Pickling перечислений, созданных с помощью функционального API, может быть сложным, т. к. детали реализации стека фреймов используются для того, чтобы попытаться выяснить, в каком модуле создается перечисление (например, оно не будет работать, если вы используете служебную функцию в отдельном модуле, а также может не работать на IronPython или Jython). Решение состоит в том, чтобы явно указать имя модуля следующим образом:

>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', module=__name__)

Предупреждение. Если модуль module не предоставлен и Enum не может определить, что это такое, то новые члены Enum будут недоступны для выбора. Чтобы сохранить ошибки ближе к источнику, процесс pickling будет отключен.

Новый протокол pickle 4 также, в некоторых случаях, полагается на то, что __qualname__ устанавливается в место, где pickle сможет найти класс. Например, если класс был доступен в классе SomeData в глобальной области:

>>> Animal = Enum('Animal', 'ANT BEE CAT DOG', qualname='SomeData.Animal')

Полная сигнатура:

Enum(
     value='NewEnumName', 
     names=<...>, *, module='...', 
     qualname='...', type=<mixed-in class>, start=1
)

где:

  • value: то, что новый класс Enum запишет в качестве своего имени.
  • names: члены Enum. Это может быть строка, разделенная пробелами или запятыми (значения будут начинаться с 1, если не указано иное):

    'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'
    

    или итератор имен:

    ['RED', 'GREEN', 'BLUE']
    

    или итератор пар (имя, значение):

    [('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]
    

    или отображение (словарь):

    {'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}
    
  • module: имя модуля, в котором можно найти новый класс Enum.

  • qualname: где в модуле можно найти новый класс Enum.

  • type: тип для добавления в новый класс Enum.

  • start: число, с которого можно начать отсчет, если будут переданы только имена.