【问题标题】:is it possible to directly import an enum field in Python 3?是否可以在 Python 3 中直接导入枚举字段?
【发布时间】:2017-10-30 13:19:37
【问题描述】:

假设我有以下枚举:

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

是否有可能以某种方式直接从此枚举中导入字段?

例如:

from mymodule.LineStyle import SOLID, DASHED  # does not work

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

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

SOLID = LineStyle.SOLID
DASHED = LineStyle.DASHED
DASHDOT = LineStyle.DASHDOT
DOTTED = LineStyle.DOTTED

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

【问题讨论】:

  • 导入机制无法访问类中的项目。所以,没有。
  • 请问你为什么不能像LineStyle.SOLID那样使用它们?为什么你需要一个单独的变量呢?
  • 这只是为了美观/代码简洁。拥有诸如plot_some_stuff(color=Color.RED, line_style=LineStyle.DOTTED) 而不仅仅是plot_some_stuff(color=RED, line_style=DOTTED) 之类的东西是多余的。
  • 对于化妆品,我倾向于使用合格的进口产品,也许,将 Color 作为 C 进口?

标签: python python-3.x enums python-import


【解决方案1】:

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

可以将这些名称自动分配给全局变量,方法是将 __members__ attribute 中的所有信息添加到模块全局变量中:

globals().update(LineStyle.__members__)

globals() function 为您提供对当前模块命名空间的引用,让您可以动态地将名称添加到该命名空间。 LineStyle.__members__ 属性是名称到值的映射(包括aliases),因此上面将所有名称添加到全局命名空间中:

>>> 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'>

如果您不希望其中包含别名,请使用 for 循环,遍历 LineStyle 对象。这只会为您提供成员对象,然后您可以从中提取名称:

for member in LineStyle:
    globals()[member.name] = member

【讨论】:

  • 动态生成字段有点违背了我首先使用枚举的目的,即拥有“伪强类型”/IDE友好代码,所以我想我会坚持我的解决方法...无论如何,谢谢。
  • @nicoulaj:当然可以,但是要付出必须重复自己的代价。就个人而言,我根本不会制作全局变量。
【解决方案2】:

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

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


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

【讨论】:

    猜你喜欢
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-04
    相关资源
    最近更新 更多