intflag - python enum to string
Convertir cadena a Enum en Python (6)
Me pregunto cuál es la forma correcta de convertir (deserializar) una cadena a una clase Enum de Python.
Parece que
getattr(YourEnumType, str)
hace el trabajo, pero no estoy seguro de si es lo suficientemente seguro.
Solo para ser más específico, me gustaría convertir una cadena de
''debug''
en un objeto Enum como este:
class BuildType(Enum):
debug = 200
release = 400
Esta funcionalidad ya está integrada en Enum [1]:
>>> from enum import Enum
>>> class Build(Enum):
... debug = 200
... build = 400
...
>>> Build[''debug'']
<Build.debug: 200>
[1] Documentos oficiales:
Enum programmatic access
Mi solución al problema similar a Java. Espero que ayude a alguien ...
from enum import Enum, auto
class SignInMethod(Enum):
EMAIL = auto(),
GOOGLE = auto()
@staticmethod
def value_of(value) -> Enum:
for m, mm in SignInMethod.__members__.items():
if m == value:
return mm
sim = SignInMethod.value_of(''EMAIL'')
print("""TEST
1). {0}
2). {1}
3). {2}
""".format(sim, sim.name, isinstance(sim, SignInMethod)))
Otra alternativa (especialmente útil si sus cadenas no se asignan 1-1 a sus casos enum) es agregar un
staticmethod
a 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 puede hacer
question_type = QuestionType.from_str(''singleSelect'')
Solo quiero notificar que esto no funciona en Python 3.6
class MyEnum(Enum):
a = ''aaa''
b = 123
print(MyEnum(''aaa''), MyEnum(123))
Tendrás que dar los datos como una tupla como esta
MyEnum((''aaa'',))
EDITAR: Esto resulta ser falso. Créditos a un comentarista por señalar mi error
Una mejora a la respuesta de @rogueleaderr:
class QuestionType(enum.Enum):
MULTI_SELECT = "multi"
SINGLE_SELECT = "single"
@classmethod
def from_str(cls, label):
if label in (''single'', ''singleSelect''):
return cls.SINGLE_SELECT
elif label in (''multi'', ''multiSelect''):
return cls.MULTI_SELECT
else:
raise NotImplementedError
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 Enum 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