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
Answer from sophros on Stack OverflowConvert string to Enum in Python - Stack Overflow
python - Getting value of enum on string conversion - Stack Overflow
Find enum value by enum name in string - Python - Stack Overflow
Is there a way to somehow link string with enum?
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
By reading the documentation (i.e., I didn't try it because I use an older version of Python, but I trust the docs), since Python 3.11 you can do the following:
from enum import StrEnum
class Direction(StrEnum):
NORTH = 'north'
SOUTH = 'south'
print(Direction.NORTH)
>>> north
Note that it looks like when subclassing StrEnum, defining the enum fields as single-value tuples will make no difference at all and would also be treated as strings, like so:
class Direction(StrEnum):
NORTH = 'north', # notice the trailing comma
SOUTH = 'south'
Please refer to the docs and the design discussion for further understanding.
If you're running python 3.6+, execute pip install StrEnum, and then you can do the following (confirmed by me):
from strenum import StrEnum
class URL(StrEnum):
GOOGLE = 'www.google.com'
STACKOVERFLOW = 'www.stackoverflow.com'
print(URL.STACKOVERFLOW)
>>> www.stackoverflow.com
You can read more about it here.
Also, this was mentioned in the docs - how to create your own enums based on other classes:
While IntEnum is part of the enum module, it would be very simple to implement independently:
class IntEnum(int, Enum): pass This demonstrates how similar derived enumerations can be defined; for example a StrEnum that mixes in str instead of int.
Some rules:
When subclassing Enum, mix-in types must appear before Enum itself in the sequence of bases, as in the IntEnum example above.
While Enum can have members of any type, once you mix in an additional type, all the members must have values of that type, e.g. int above. This restriction does not apply to mix-ins which only add methods and donโt specify another type.
When another data type is mixed in, the value attribute is not the same as the enum member itself, although it is equivalent and will compare equal.
%-style formatting: %s and %r call the Enum classโs str() and repr() respectively; other codes (such as %i or %h for IntEnum) treat the enum member as its mixed-in type.
Formatted string literals, str.format(), and format() will use the mixed-in typeโs format() unless str() or format() is overridden in the subclass, in which case the overridden methods or Enum methods will be used. Use the !s and !r format codes to force usage of the Enum classโs str() and repr() methods.
Source: https://docs.python.org/3/library/enum.html#others
This functionality is already built in to Enum:
>>> from enum import Enum
>>> class Build(Enum):
... debug = 200
... build = 400
...
>>> Build['debug']
<Build.debug: 200>
The member names are case sensitive, so if user-input is being converted you need to make sure case matches:
an_enum = input('Which type of build?')
build_type = Build[an_enum.lower()]
Another alternative (especially useful if your strings don't map 1-1 to your enum cases) is to add a staticmethod to your Enum, e.g.:
class QuestionType(enum.Enum):
MULTI_SELECT = "multi"
SINGLE_SELECT = "single"
@staticmethod
def from_str(label):
if label in ('single', 'singleSelect'):
return QuestionType.SINGLE_SELECT
elif label in ('multi', 'multiSelect'):
return QuestionType.MULTI_SELECT
else:
raise NotImplementedError
Then you can do question_type = QuestionType.from_str('singleSelect')
You are printing the enum object. Use the .value attribute if you wanted just to print that:
print(D.x.value)
See the Programmatic access to enumeration members and their attributes section:
If you have an enum member and need its name or value:
>>> >>> member = Color.red >>> member.name 'red' >>> member.value 1
You could add a __str__ method to your enum, if all you wanted was to provide a custom string representation:
class D(Enum):
def __str__(self):
return str(self.value)
x = 1
y = 2
Demo:
>>> from enum import Enum
>>> class D(Enum):
... def __str__(self):
... return str(self.value)
... x = 1
... y = 2
...
>>> D.x
<D.x: 1>
>>> print(D.x)
1
I implemented access using the following
class D(Enum):
x = 1
y = 2
def __str__(self):
return '%s' % self.value
now I can just do
print(D.x) to get 1 as result.
You can also use self.name in case you wanted to print x instead of 1.