[python] 파이썬에서 문자열을 Enum으로 변환

문자열을 Python의 Enum 클래스로 변환 (직렬화)하는 올바른 방법이 무엇인지 궁금합니다. 일을하는 것처럼 보이지만 getattr(YourEnumType, str)그것이 충분히 안전한지 확실하지 않습니다.

좀 더 구체적으로 말하면 다음과 같이 'debug'문자열을 Enum 객체 로 변환하고 싶습니다.

class BuildType(Enum):
    debug = 200
    release = 400



답변

이 기능은 이미 Enum [1]에 내장되어 있습니다.

>>> from enum import Enum
>>> class Build(Enum):
...   debug = 200
...   build = 400
... 
>>> Build['debug']
<Build.debug: 200>

[1] 공식 문서 : Enum programmatic access


답변

또 다른 대안 (특히 문자열이 1-1을 열거 형 사례에 매핑하지 않는 경우에 유용합니다)는에 다음을 추가하는 staticmethod것입니다 Enum.

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

그럼 넌 할 수있어 question_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)

아니면 문자열을 알려진 Enum 으로 변환해야 합니까?

class MyEnum(Enum):
    a = 'aaa'
    b = 123

print(MyEnum('aaa'), MyEnum(123))

또는:

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


답변

문제에 대한 Java와 같은 솔루션. 누군가에게 도움이되기를 바랍니다 …

    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.upper():
                    return mm


    sim = SignInMethod.value_of('EMAIL')
    print("""TEST
    1). {0}
    2). {1}
    3). {2}
    """.format(sim, sim.name, isinstance(sim, SignInMethod)))


답변

@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


답변

파이썬 3.6에서는 작동하지 않습니다.

class MyEnum(Enum):
    a = 'aaa'
    b = 123

print(MyEnum('aaa'), MyEnum(123))

이처럼 튜플로 데이터를 제공해야합니다.

MyEnum(('aaa',))

편집 : 이것은 거짓으로 판명되었습니다. 내 실수를 지적한 해설자에게 크레딧


답변