pythonenumsclass-variables

How do I export members of a nested Python enum into the containing class?


I have a Python class that contains a state field. To define all possible states, I have declared a nested enumeration:

class Foo:
    class State(enum.Enum):
        Unloaded = enum.auto()
        Loaded = enum.auto()
        Processed = enum.auto()

    state: State

However, it is a bit cumbersome to write code like this:

if foo.state == Foo.State.Unloaded:
    do_something_with(foo)
    foo.state = Foo.State.Loaded

I want to make the enumeration members accessible directly as members of Foo (like Foo.Unloaded, Foo.Loaded and Foo.Processed). Is there a better way than just assigning them by hand?

class Foo:
    class State(enum.Enum):
        Unloaded = enum.auto()
        Loaded = enum.auto()
        Processed = enum.auto()

    Unloaded = State.Unloaded
    Loaded = State.Loaded
    Processed = State.Processed

    state: State

Solution

  • Sure, you can always dynamically do something like this. But why nest the enum at all then?

    import enum
    
    class State(enum.Enum):
        Unloaded = enum.auto()
        Loaded = enum.auto()
        Processed = enum.auto()
    
    class Foo:
        state: State
    
    
    for member in State:
        setattr(Foo, member.name, member)
    

    Or, without the loop:

    vars(Foo).update(State.__members__)
    

    Note, in general, nesting class definitions is not a common construct in Python. Even if I wanted something like your original approach (I happen to think requiring Foo.State.whatever is not cumbersome but good if you are going to have nesting), then you would just do:

    import enum
    
    class State(enum.Enum):
        Unloaded = enum.auto()
        Loaded = enum.auto()
        Processed = enum.auto()
    
    class Foo:
        State = State
        state: State
    

    Which is probably what I would use if I wanted that. But frankly, I would probably just leave state at the same level as Foo. So what I would probably just use is:

    import enum
    
    
    class State(enum.Enum):
        Unloaded = enum.auto()
        Loaded = enum.auto()
        Processed = enum.auto()
    
    class Foo:
        state: State