How can I construct an enum.Enum from a dictionary of values?

大兔子大兔子 提交于 2020-08-04 04:26:17

问题


I'd like to generate some types at runtime from a config file. For simplity, let's assume I already have the data loaded as a python dictionary:

color_values = dict(RED = 1, YELLOW = 2, GREEN = 3)

How can I transform this into the type (using enum)

class Color(enum.Enum):
    RED = 1
    YELLOW = 2
    GREEN = 3

The following doesn't work

def make_enum(name, values):
    return type(name, (enum.Enum,), values)
>>> Color = make_enum('Color', color_values)
AttributeError: 'dict' object has no attribute '_member_names'

回答1:


Color = Enum('Color', color_values)

Tada! There's a provided API for that. You can also give it an iterable of name-value pairs, or an iterable of just names (in which case the values will be auto-filled starting from 1), or a whitespace- or comma-separated string of names (which will also auto-fill values).




回答2:


Here's one super-hacky approach that seems to work:

def make_enum(name, values):
    _k = _v = None
    class TheEnum(enum.Enum):
        nonlocal _k, _v
        for _k, _v in values.items():
            locals()[_k] = _v
    TheEnum.__name__ = name
    return TheEnum

We have to use nonlocal there to stop Enum complaining about the keys k and v being duplicated.




回答3:


And another one that chooses to hit the metaclass internals instead:

def make_enum(name, values):
    meta = type(enum.Enum)
    bases = (enum.Enum,)
    dict = meta.__prepare__(name, bases)
    for k, v in values.items():
        dict[k] = v
    return meta(name, bases, dict)

Or with less __dunder__:

import types
def make_enum(name, values):
    def _update(d1, d2):
        for k, v in d2.items():
            d1[k] = v  # calls __setitem__
    return types.new_class(name, (enum.Enum,), None, lambda ns: _update(ns,values))


来源:https://stackoverflow.com/questions/47299036/how-can-i-construct-an-enum-enum-from-a-dictionary-of-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!