Convertir cadena a Enum en Python

Resuelto Vladius asked hace 7 años • 10 respuestas

¿Cuál es la forma correcta de convertir una cadena en una instancia correspondiente de una Enumsubclase? 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.debugun resultado?

Vladius avatar Dec 31 '16 17:12 Vladius
Aceptado

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()]
Ethan Furman avatar Dec 31 '2016 15:12 Ethan Furman

Otra alternativa (especialmente útil si sus cadenas no se asignan 1-1 a sus casos de enumeración) es agregar a staticmethodsu 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')

rogueleaderr avatar Mar 01 '2018 23:03 rogueleaderr
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
ADR avatar Dec 31 '2016 11:12 ADR