Convert string to Enum in Python
Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Sunrise at the Stream
--
Chapters
00:00 Question
00:35 Accepted answer (Score 488)
00:59 Answer 2 (Score 42)
01:32 Answer 3 (Score 14)
02:08 Answer 4 (Score 14)
02:49 Thank you
--
Full question
https://stackoverflow.com/questions/4140...
Accepted answer links:
[Enum]: https://docs.python.org/3/library/enum.h...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #string #enums #typeconversion
#avk47
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Sunrise at the Stream
--
Chapters
00:00 Question
00:35 Accepted answer (Score 488)
00:59 Answer 2 (Score 42)
01:32 Answer 3 (Score 14)
02:08 Answer 4 (Score 14)
02:49 Thank you
--
Full question
https://stackoverflow.com/questions/4140...
Accepted answer links:
[Enum]: https://docs.python.org/3/library/enum.h...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #string #enums #typeconversion
#avk47
ACCEPTED ANSWER
Score 596
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()]
ANSWER 2
Score 48
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')
ANSWER 3
Score 17
def custom_enum(typename, items_dict):
class_definition = """
from enum import Enum
class {}(Enum):
{}""".format(typename, '\n '.join(['{} = {}'.format(k, v) for k, v in items_dict.items()]))
namespace = dict(__name__='enum_%s' % typename)
exec(class_definition, namespace)
result = namespace[typename]
result._source = class_definition
return result
MyEnum = custom_enum('MyEnum', {'a': 123, 'b': 321})
print(MyEnum.a, MyEnum.b)
Or do you need to convert string to known Enum?
class MyEnum(Enum):
a = 'aaa'
b = 123
print(MyEnum('aaa'), MyEnum(123))
Or:
class BuildType(Enum):
debug = 200
release = 400
print(BuildType.__dict__['debug'])
print(eval('BuildType.debug'))
print(type(eval('BuildType.debug')))
print(eval(BuildType.__name__ + '.debug')) # for work with code refactoring
ANSWER 4
Score 15
My Java-like solution to the problem. Hope it helps someone...
from enum import Enum, auto
class SignInMethod(Enum):
EMAIL = auto(),
GOOGLE = auto()
@classmethod
def value_of(cls, value):
for k, v in cls.__members__.items():
if k == value:
return v
else:
raise ValueError(f"'{cls.__name__}' enum not found for '{value}'")
sim = SignInMethod.value_of('EMAIL')
assert sim == SignInMethod.EMAIL
assert sim.name == 'EMAIL'
assert isinstance(sim, SignInMethod)
# SignInMethod.value_of("invalid sign-in method") # should raise `ValueError`