pythonpython-3.xstringenums

String-based enum in Python


To encapsulate a list of states I am using enum module:

from enum import Enum

class MyEnum(Enum):
    state1='state1'
    state2 = 'state2'

state = MyEnum.state1
MyEnum['state1'] == state  # here it works
'state1' == state  # here it does not throw but returns False (fail!)

However, the issue is that I need to seamlessly use the values as strings in many contexts in my script, like:

select_query1 = select(...).where(Process.status == str(MyEnum.state1))  # works but ugly

select_query2 = select(...).where(Process.status == MyEnum.state1)  # throws exeption

How to do it avoiding calling additional type conversion (str(state) above) or the underlying value (state.value)?


Solution

  • It seems that it is enough to inherit from str class at the same time as Enum:

    from enum import Enum
    
    class MyEnum(str, Enum):
        state1 = 'state1'
        state2 = 'state2'
    

    The tricky part is that the order of classes in the inheritance chain is important as this:

    class MyEnum(Enum, str):
        state1 = 'state1'
        state2 = 'state2'
    

    throws:

    TypeError: new enumerations should be created as `EnumName([mixin_type, ...] [data_type,] enum_type)`
    

    With the correct class the following operations on MyEnum are fine:

    print('This is the state value: ' + state)
    

    As a side note, it seems that the special inheritance trick is not needed for formatted strings which work even for Enum inheritance only:

    msg = f'This is the state value: {state}'  # works without inheriting from str