Search code examples
python-3.xenumsattributesglobal

How to allow a class attribute to be accessible from the module global context in Python?


I defined an enum class and would like to be able to use its attributes without need to access it through class name. I mean:

class MyEnum:
    ONE = 1
    TWO = 2
    ...

if MyEnum.ONE == 1:
    "Typic use"
if TWO == 2:
    "My desire"

Is there a way to do this?


In my specific context, I'm calculating points externality of a window through Cohen–Sutherland algorithm, so I have the following code:

class Externality:
    INSIDE = 0
    LEFT = 1
    RIGTH = 2
    BELLOW = 4
    ABOVE = 8
# And at some point:
((x, y), externality) = actual

if not Externality.INSIDE in externality:
    del cohen_sutherland_list[0]

So, the needed of express Enum's name to access its items make the if statement (and the whole code) a little more verbose and redundant.


Solution

  • First things first: inherit from Enum.


    Like everything in Python, all you need to do is assign the names:

    from enum import Enum
    
    class MyEnum(Enum):
        ONE = 1
        TWO = 2
    
    ONE = MyEnum.ONE
    TWO = MyEnum.TWO
    

    That can get annoying fast, so a helper function would be nice:

    def export_enum(enum_cls, env):
        for member in enum_cls:
            env[member.name] = member
    

    and in use:

    >>> export_enum(MyEnum, globals())
    >>> TWO
    <MyEnum.TWO: 2>
    

    If you use aenum1 the export() function is already available, and can be used as a decorator:

    from aenum import Enum, export
    
    @export(globals())
    class MyEnum(Enum):
        ONE = 1
        TWO = 2
    

    1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.