是否有可能直接导入Python 3中的枚举字段?

nic*_*laj 6 python enums python-import python-3.x

假设我有以下枚举:

class LineStyle(Enum):
    SOLID = 'solid'
    DASHED = 'dashed'
    DASHDOT = 'dashdot'
    DOTTED = 'dotted'
Run Code Online (Sandbox Code Playgroud)

有可能以某种方式直接导入此枚举中的字段吗?

例如:

from mymodule.LineStyle import SOLID, DASHED  # does not work
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一解决方法是将所有枚举字段声明为模块变量:

class LineStyle(Enum):
    SOLID = 'solid'
    DASHED = 'dashed'
    DASHDOT = 'dashdot'
    DOTTED = 'dotted'

SOLID = LineStyle.SOLID
DASHED = LineStyle.DASHED
DASHDOT = LineStyle.DASHDOT
DOTTED = LineStyle.DOTTED
Run Code Online (Sandbox Code Playgroud)

有没有更优雅的方式来做到这一点?

Mar*_*ers 11

随着号import可以在当前的命名空间指向模块对象本身永远只能添加引用,或在模块中的顶级名称.枚举值不是模块中的顶级名称,除非您明确地将它们放在那里,就像在您的解决方法中一样.

可以通过将__members__属性中的所有信息添加到模块全局变量自动将这些名称分配给全局变量:

globals().update(LineStyle.__members__)
Run Code Online (Sandbox Code Playgroud)

globals()函数为您提供了对当前模块的命名空间的引用,允许您动态地向该命名空间添加名称.该LineStyle.__members__属性是名称到值的映射(包括别名),因此上面将所有名称添加到全局名称空间:

>>> from enum import Enum
>>> class LineStyle(Enum):
...     SOLID = 'solid'
...     DASHED = 'dashed'
...     DASHDOT = 'dashdot'
...     DOTTED = 'dotted'
...
>>> SOLID
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'SOLID' is not defined
>>> globals().update(LineStyle.__members__)
>>> SOLID
<LineStyle.SOLID: 'solid'>
Run Code Online (Sandbox Code Playgroud)

如果您不想包含其中的别名,请使用for循环,迭代LineStyle对象.这只会为您提供成员对象,然后您可以从中提取名称:

for member in LineStyle:
    globals()[member.name] = member
Run Code Online (Sandbox Code Playgroud)

  • 动态生成字段有点违背了我首先使用枚举的目的,即拥有“伪强类型”/IDE 友好的代码,所以我想我会坚持使用我的解决方法......无论如何,谢谢。 (2认同)

Eth*_*man 7

您不能直接导入enum成员,但可以使用装饰器将 Enum 成员自动添加到globals(),然后就可以导入了。例如:

def global(enum):
    globals().update(enum.__members__)
    return enum


@global
class LineStyle(Enum):
    SOLID = 'solid'
    DASHED = 'dashed'
    DASHDOT = 'dashdot'
    DOTTED = 'dotted'
Run Code Online (Sandbox Code Playgroud)