Python에서 문자열을 Enum으로 변환
스트링을 해당 인스턴스로 변환하는 올바른 방법은 무엇입니까?Enum
서브클래스?그런 것 같다getattr(YourEnumType, str)
효과가 있지만 충분히 안전한지는 잘 모르겠어요
예를 들어 다음과 같은 열거형이 있다고 가정합니다.
class BuildType(Enum):
debug = 200
release = 400
문자열 지정'debug'
, 어떻게 하면BuildType.debug
그 결과?
이 기능은 에 이미 포함되어 있습니다.
>>> from enum import Enum
>>> class Build(Enum):
... debug = 200
... build = 400
...
>>> Build['debug']
<Build.debug: 200>
멤버명은 대소문자를 구분하기 때문에 사용자 입력이 변환되는 경우 대소문자가 일치하는지 확인해야 합니다.
an_enum = input('Which type of build?')
build_type = Build[an_enum.lower()]
또 다른 대안(특히 문자열이 열거형 케이스에 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')
문제에 대한 자바와 같은 솔루션.도움이 됐으면 좋겠는데...
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`
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
@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
부터MyEnum['dontexist']
에러가 발생합니다.KeyError: 'dontexist'
사일런트 에러(return None 등)가 발생할 수 있습니다.이 경우 다음 정적 방법을 사용할 수 있습니다.
class Statuses(enum.Enum):
Unassigned = 1
Assigned = 2
@staticmethod
def from_str(text):
statuses = [status for status in dir(
Statuses) if not status.startswith('_')]
if text in statuses:
return getattr(Statuses, text)
return None
Statuses.from_str('Unassigned')
클래스 시그니처를 다음과 같이 변경합니다.
class BuildType(str, Enum):
python 3.6에서는 동작하지 않는다는 것을 알려드립니다.
class MyEnum(Enum):
a = 'aaa'
b = 123
print(MyEnum('aaa'), MyEnum(123))
이렇게 데이터를 태플 형태로 제공해야 합니다.
MyEnum(('aaa',))
EDIT: 이것은 거짓으로 판명되었습니다.나의 실수를 지적한 코멘터에게 크레딧을 주다
언급URL : https://stackoverflow.com/questions/41407414/convert-string-to-enum-in-python
'programing' 카테고리의 다른 글
PHP 쇼트태그를 유효하게 하는 방법 (0) | 2022.09.28 |
---|---|
양식에서 단추를 누르면 페이지 새로 고침 (0) | 2022.09.28 |
PHP에서 변수의 존재를 테스트하는 가장 좋은 방법은 isset()이(가) 명확하게 끊어졌습니다. (0) | 2022.09.28 |
JavaScript를 사용하여 운영체제에 대한 자세한 내용을 확인하는 방법 (0) | 2022.09.28 |
PHP - 연관 배열 시작 부분에 항목 추가 (0) | 2022.09.28 |