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

Let's say I have the following enumeration:

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

Is there any way to directly import fields from this enumeration?

For instance:

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

The only workaround I could think of is to declare all enumeration 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?

+6
source share
2 answers

No. With import you can only add links in the current namespace that point to the module object itself or to top-level names in the module. Enumerated values ​​are not top-level names in a module unless you explicitly put them there, as in your workaround.

You can automate the assignment of these names to global variables by adding all the information from the __members__ attribute to the global variables of your module:

 globals().update(LineStyle.__members__) 

The globals() function gives you a reference to the namespace of the current module, allowing you to dynamically add names to this namespace. LineStyle.__members__ is a name-to-value mapping (including aliases ), so the above adds all the 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 do not want aliases to be included in this, use the for , LineStyle object. This only gives you member objects from which you can then extract the name:

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

You cannot import an enum member directly, but you can use a decorator to automatically add Enum members to globals() , which will then be imported. For instance:

 def global(enum): globals.update(enum.__members__) return enum @global class LineStyle(Enum): SOLID = 'solid' DASHED = 'dashed' DASHDOT = 'dashdot' DOTTED = 'dotted' 
0
source

Source: https://habr.com/ru/post/1272999/


All Articles