2015-01-24 3 views
4

Я понимаю, что это NOT стандартный пример использования, но мне нужно динамически добавлять элементы в производный класс IntEnum в Python. Обратите внимание, что динамического создания Enum с использованием функционального API недостаточно. Мне нужно добавить элементы в существующее перечисление. Как я могу это сделать?Добавление членов в Python Enums

Фон: для тех из вас, кто задается вопросом, почему кто-то хочет это сделать. Я обертываю библиотеку, и значения для перечисления определяются в библиотеке. Я могу запросить имена и значения, используя библиотечный API. Но я не могу сделать это при инициализации, поскольку это зависит от компонентов, которые динамически загружаются библиотекой по запросу пользователя. Я могу загрузить все компоненты при запуске и использовать функциональный API для создания перечисления при импорте, но это требует много времени и имеет побочные эффекты.

+1

- не весь смысл ENUM неизменяемости? – MightyPork

+1

Вы не можете. Даже * подклассы, которые расширяют существующие перечисления *, защищены. –

+0

@MartijnPieters Любое предложение для данного конкретного случая использования? – Hernan

ответ

8

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

from enum import Enum 

names = [m.name for m in ExistingEnum] + ['newname1', 'newname2'] 
ExistingEnum = Enum('ExistingEnum', names) 

но любые существующих ссылки (например, в других модулях) будет продолжать использовать старое определение.

names может быть: имена

  • строки, содержащие члены, разделенные либо с пробелами или запятыми. Значения увеличиваются на 1 от start (который может быть установлен как аргумент ключевого слова и по умолчанию равен 1).
  • Итерируемое имя участника (как в коде выше). Значения увеличиваются на 1 от start.
  • Итерируемые пары (имя члена, значение).
  • Отображение пар имени члена -> пары значений.
+1

Как я уже упоминал, это не вариант по тем же причинам, которые вы описываете. Спасибо в любом случае – Hernan

+0

@Hernan: это ваш * единственный * вариант при использовании библиотеки enum. –

9

Это работа для extend_enum функции от aenum library .


Несколько образцов Enum s:

class Color(Enum): 
    black = 0 

class ColorHelp(Enum): 
    _init_ = 'value __doc__' 
    black = 0, 'the absence of color' 

extend_enum в действии:

from aenum import extend_enum 

extend_enum(Color, 'white', 1) 
print Color, list(Color) 
print repr(Color.black), Color.black, repr(Color.white), Color.white 
print 

extend_enum(ColorHelp, 'white', 1, 'the presence of every color') 
print ColorHelp, list(ColorHelp) 
print repr(ColorHelp.black), ColorHelp.black, ColorHelp.black.__doc__, repr(ColorHelp.white), ColorHelp.white, ColorHelp.white.__doc__ 

Который дает нам:

<enum 'Color'> [<Color.black: 0>, <Color.white: 1>] 
<Color.black: 0> Color.black <Color.white: 1> Color.white 

<enum 'ColorHelp'> [<ColorHelp.black: 0>, <ColorHelp.white: 1>] 
<ColorHelp.black: 0> ColorHelp.black the absence of color <ColorHelp.white: (1, 'the presence of every color')> ColorHelp.white None 

Раскрытие информации: Я являюсь автором Python stdlib Enum, enum34 backport и Advanced Enumeration (aenum).

+0

Я получаю «Файл» /home/vamalov/.local/lib/python3.5/site-packages/aenum/__init__.py », строка 2166, в extend_enum для canonical_value в canonical_member._values_: AttributeError: 'MachineName' объект не имеет атрибута '_values_' ", где MachineName является обычным перечислением python. Этот метод все еще работает? – likern

+0

@likern: Заглядывая в него ... –

Смежные вопросы