如何让 Enum 的成员进入全局命名空间?

How does one get an Enum's members into the global namespace?

Python 现在有一个枚举类型(3.4 with PEP 435, and alse backported 中的新功能),虽然命名空间是个好东西,但有时枚举更像常量一样使用,枚举成员应该存在于全局(呃,模块)命名空间。

所以代替:

Constant(Enum):
    PI = 3.14

...

area = Constant.PI * r * r

我只能说:

area = PI * r * r

有没有简单的方法从 Constant.PIPI

官方支持的方法是这样的:

globals().update(Constant.__members__)

这是可行的,因为 __members__ 是一个类似于 dict 的对象,它包含枚举 class.

的名称和成员

我个人觉得这很丑陋,所以我通常将以下方法添加到我的 Enum classes:

@classmethod
def export_to(cls, namespace):
    namespace.update(cls.__members__)

然后在我的顶级代码中我可以说:

Constant.export_to(globals())

注意:只有当模块只有一个这样的导出枚举时,才能将枚举导出到全局命名空间。如果你有多个,最好为枚举本身使用一个更短的别名,并使用它而不是污染全局命名空间:

class Constant(Enum):
    PI = ....
C = Constant

area = C.PI * r * r

FWIW — 这更像是评论而不是答案 — 下面是我编写的一些旧代码的函数的开头,该代码实现了自己命名的 int-like 已添加的枚举值对象默认情况下到全局命名空间(不涉及命名容器 Enum class)。但是,它所做的事情与您自己的答案中显示的类似,所以我认为这是一个很好的整体方法,因为它对我来说效果很好。

def Enum(names, values=None, namespace=None):
    """Function to assign values to names given and add them to a
    namespace. Default values are a sequence of integers starting at
    zero. Default namespace is the caller's globals."""
    if namespace is None:
        namespace = sys._getframe(1).f_globals  # caller's globals

    pairs = _paired(names, values)
    namespace.update(pairs)  # bind names to cooresponding named numbers
        . . .

重点是,就当前 Enum class 模块的实现而言,我建议添加类似的东西或您自己的 def export_to() 方法在下一个 Python 版本中回答 Enum base class,因此它会自动可用。