【问题标题】:How can I construct an enum.Enum from a dictionary of values?如何从值字典构造 enum.Enum?
【发布时间】:2017-11-15 03:48:06
【问题描述】:

我想在运行时从配置文件生成一些类型。为简单起见,假设我已经将数据加载为 python 字典:

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

如何将其转换为类型(使用enum

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

以下不起作用

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'

【问题讨论】:

  • 你应该使用 OrderedDict 而不是普通的 dict。
  • @IoannisFilippidis:在我的辩护中,我记得这个问题是一个前enum.Enum,它只会告诉我使用它。当然,你是对的,它显示了我需要的示例。

标签: python enums python-3.4


【解决方案1】:
Color = Enum('Color', color_values)

Tada! 为此提供了一个 API。您还可以给它一个名称-值对的可迭代对象,或仅名称的可迭代对象(在这种情况下,值将从 1 开始自动填充),或者一个空格或逗号分隔的名称字符串(这也将自动填充值)。

【讨论】:

    【解决方案2】:

    这是一种似乎可行的超级hacky方法:

    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
    

    我们必须在那里使用nonlocal 来阻止Enum 抱怨键kv 被重复。

    【讨论】:

      【解决方案3】:

      另外一个选择使用元类内部结构:

      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)
      

      或者少用__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))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-24
        • 2023-04-10
        • 2013-12-20
        • 1970-01-01
        • 2019-03-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多