问题:在Python中将字符串转换为Enum
我想知道将字符串转换(反序列化)为Python的Enum类的正确方法是什么。似乎可以getattr(YourEnumType, str)
完成这项工作,但是我不确定它是否足够安全。
更具体地说,我想像这样将'debug'
字符串转换为Enum对象:
class BuildType(Enum):
debug = 200
release = 400
回答 0
此功能已内置到枚举[1]中:
>>> from enum import Enum
>>> class Build(Enum):
... debug = 200
... build = 400
...
>>> Build['debug']
<Build.debug: 200>
[1]官方文档: Enum programmatic access
回答 1
另一种选择(如果你的字符串不映射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')
回答 2
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
回答 3
我的类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)))
回答 4
对@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
回答 5
我只想通知这在python 3.6中不起作用
class MyEnum(Enum):
a = 'aaa'
b = 123
print(MyEnum('aaa'), MyEnum(123))
您将不得不像这样以元组形式提供数据
MyEnum(('aaa',))
编辑:这被证明是错误的。感谢指出我的错误的评论者