将字符串转换为Enum子类的对应实例的正确方法是什么?似乎getattr(YourEnumType, str)做的工作,但我不确定它是否足够安全。
举个例子,假设我有一个枚举
class BuildType(Enum):
debug = 200
release = 400
给定字符串'调试',我怎么能得到BuildType.debug作为结果?
将字符串转换为Enum子类的对应实例的正确方法是什么?似乎getattr(YourEnumType, str)做的工作,但我不确定它是否足够安全。
举个例子,假设我有一个枚举
class BuildType(Enum):
debug = 200
release = 400
给定字符串'调试',我怎么能得到BuildType.debug作为结果?
当前回答
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))
Or:
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
其他回答
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))
Or:
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
更改你的类签名为:
class BuildType(str, Enum):
我的类似java的解决方案。希望它能帮助到某人…
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`
这个功能已经内置在Enum中:
>>> 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()]
我只是想通知这在python 3.6中不起作用
class MyEnum(Enum):
a = 'aaa'
b = 123
print(MyEnum('aaa'), MyEnum(123))
你必须像这样以元组的形式给出数据
MyEnum(('aaa',))
编辑: 事实证明这是错误的。感谢一位指出我错误的评论者