Convertir cadena a Enum en Python
¿Cuál es la forma correcta de convertir una cadena en una instancia correspondiente de una Enum
subclase? Parece que getattr(YourEnumType, str)
funciona, pero no estoy seguro de si es lo suficientemente seguro.
Como ejemplo, supongamos que tengo una enumeración como
class BuildType(Enum):
debug = 200
release = 400
Dada la cadena 'debug'
, ¿cómo puedo obtener BuildType.debug
un resultado?
Esta funcionalidad ya está integrada en Enum
:
>>> from enum import Enum
>>> class Build(Enum):
... debug = 200
... build = 400
...
>>> Build['debug']
<Build.debug: 200>
Los nombres de los miembros distinguen entre mayúsculas y minúsculas, por lo que si se convierten las entradas del usuario, debe asegurarse de que coincidan entre mayúsculas y minúsculas:
an_enum = input('Which type of build?')
build_type = Build[an_enum.lower()]
Otra alternativa (especialmente útil si sus cadenas no se asignan 1-1 a sus casos de enumeración) es agregar a staticmethod
su Enum
, por ejemplo:
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
Entonces puedes hacerquestion_type = QuestionType.from_str('singleSelect')
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)
¿O necesita convertir una cadena a una enumeración conocida ?
class MyEnum(Enum):
a = 'aaa'
b = 123
print(MyEnum('aaa'), MyEnum(123))
O:
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