【问题标题】:How to get new Enum with members as enum using EnumMeta Python 3.6如何使用 EnumMeta Python 3.6 获取具有成员作为枚举的新枚举
【发布时间】:2019-11-23 05:21:03
【问题描述】:

我正在尝试将一些代码从 python 2 翻译成 python 3,但遇到了问题:

from enum import Enum, EnumMeta


class KeyCode(Enum):
    A = 1
    B = 2
    C = 3


class KeyMeta(EnumMeta):
    def __new__(mcs, name, bases, dct):
        dct.update({e.name: e.value for e in KeyCode})
        return super(KeyMeta, mcs).__new__(mcs, name, bases, dct)


class Key(Enum, metaclass=KeyMeta):
    pass


print(repr(Key.A))

问题是python2的Key.Aenum < Key.A: 1>,而python3是< class 'int'>

【问题讨论】:

标签: python enums


【解决方案1】:

在 Python 3 中,dct 对象不是常规字典,而是专用于帮助创建枚举的子类,通过元类的 __prepare__ attribute 设置。但是,它是 update() 方法,并没有从基本字典中更改。

它通常期望通过它的__setitem__ method 设置成员(例如dct[name] = value);在您的 __new__ 方法中也这样做:

class KeyMeta(EnumMeta):
    def __new__(mcs, name, bases, dct):
        for e in KeyCode:
            dct[e.name] = e.value
        return super(KeyMeta, mcs).__new__(mcs, name, bases, dct)

现在每个名称ABC 都被记录为枚举成员名称,EnumMeta 类从那里获取它。如果不使用专门的 __setitem__ 实现,名称将被视为其他类型的属性。

通过上述更改,您将获得预期的输出:

>>> class Key(Enum, metaclass=KeyMeta):
...     pass
...
>>> Key.A
<Key.A: 1>

同样的 for e in KeyCode: 循环也将在 Python 2 中继续工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 2015-08-08
    相关资源
    最近更新 更多