Класс 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
: число, с которого можно начать отсчет, если будут переданы только имена.