Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to directly import an enum field in Python 3?

Let's say I have the following enum:

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

Is it possible to somehow directly import fields from this enum ?

Eg:

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

The only workaround I could think of is declaring all enums fields as module variables:

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

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

Is there a more elegant way to do this ?

like image 392
nicoulaj Avatar asked Oct 30 '17 13:10

nicoulaj


People also ask

What is import enum in Python?

Enum is a class in python for creating enumerations, which are a set of symbolic names (members) bound to unique, constant values. The members of an enumeration can be compared by these symbolic anmes, and the enumeration itself can be iterated over. An enum has the following characteristics.

What is enum Auto ()?

Syntax : enum.auto() Automatically assign the integer value to the values of enum class attributes. Example #1 : In this example we can see that by using enum. auto() method, we are able to assign the numerical values automatically to the class attributes by using this method.

Does Python support enum?

Introduction to the Python Enumeration Enumeration is often called enum. Python provides you with the enum module that contains the Enum type for defining new enumerations. And you define a new enumeration type by subclassing the Enum class.


2 Answers

No. With import can only ever add references in the current namespace pointing to the module object itself, or to the top-level names in the module. Enum values are not top-level names in the module unless you explicitly put them there, like in your workaround.

You can automate assigning those names to globals, by adding all information from the __members__ attribute to your module globals:

globals().update(LineStyle.__members__)

The globals() function gives you a reference to the namespace of the current module, letting you add names to that namespace dynamically. The LineStyle.__members__ attribute is a a mapping of name to value (including aliases), so the above adds all names to the global namespace:

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

If you don't want aliases included in that, use a for loop, iterating over the LineStyle object. That only gives you the member objects, from which you can then pull the name:

for member in LineStyle:
    globals()[member.name] = member
like image 73
Martijn Pieters Avatar answered Oct 14 '22 04:10

Martijn Pieters


You cannot directly import an enum member, but you can use a decorator to auto-add the Enum members to globals(), which would then be importable. For example:

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


@global
class LineStyle(Enum):
    SOLID = 'solid'
    DASHED = 'dashed'
    DASHDOT = 'dashdot'
    DOTTED = 'dotted'
like image 38
Ethan Furman Avatar answered Oct 14 '22 03:10

Ethan Furman