Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中将字符串转换为枚举_Python_String_Serialization_Enums_Type Conversion - Fatal编程技术网

在Python中将字符串转换为枚举

在Python中将字符串转换为枚举,python,string,serialization,enums,type-conversion,Python,String,Serialization,Enums,Type Conversion,我想知道将字符串转换(反序列化)为Python的枚举类的正确方法是什么。似乎是getattr(YourEnumType,str)完成了这项工作,但我不确定它是否足够安全 更具体地说,我想将'debug'字符串转换为如下所示的枚举对象: class BuildType(Enum): debug = 200 release = 400 或者您需要将字符串转换为已知的枚举吗 class MyEnum(Enum): a = 'aaa' b = 123 print(My

我想知道将字符串转换(反序列化)为Python的枚举类的正确方法是什么。似乎是
getattr(YourEnumType,str)
完成了这项工作,但我不确定它是否足够安全

更具体地说,我想将
'debug'
字符串转换为如下所示的枚举对象:

class BuildType(Enum):
    debug = 200
    release = 400
或者您需要将字符串转换为已知的枚举吗

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

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


此功能已内置于枚举[1]中:

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

另一种选择(如果字符串未将1-1映射到枚举案例,则特别有用)是向
枚举添加
staticmethod
,例如:

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\u type=QuestionType。从\u str('singleSelect')
我只想通知您,这在python 3.6中不起作用

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

print(MyEnum('aaa'), MyEnum(123))
您必须像这样以元组的形式提供数据

MyEnum(('aaa',))
编辑:
事实证明这是错误的。感谢一位评论者指出了我的错误

这是对@rogueleader答案的改进:

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

我的类似Java的问题解决方案。希望它能帮助别人


类签名方法(枚举):
电子邮件=自动(),
GOOGLE=auto()
@类方法
def值_(cls,值):
对于cls中的k,v.\u成员\u.items():
如果k==value.upper():
返回v
sim=签名方法(“电子邮件”)的值
assert sim==SignInMethod.EMAIL
断言sim.name==“电子邮件”
断言isinstance(sim、SignInMethod)

由于
MyEnum['dontexist']
将导致错误
keyrerror:'dontexist'
,您可能希望以静默方式失败(例如,返回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')

将您的类签名更改为:

类构建类型(str,Enum):

我的意思是我想将
调试
字符串转换成这样的枚举:
python类BuildType(enum):debug=200 release=400
伟大的提示!使用
\uuuu dict\uuuu
是否与
getattr
相同?我担心名称与内部Python属性的冲突…哦。。。是,它与
getattr
相同。我看不出名称冲突的原因。您不能将关键字设置为类的字段。如果输入需要清理,那么回退值如何?类似于
Build.get('非法',Build.debug)
?@Hetzroni:
Enum
的东西没有
.get()
方法,但是你可以根据需要添加一个,或者只是创建一个基
Enum
类并始终从中继承。@Hetzroni:根据“请求原谅,而不是请求许可”原则,您可以始终将访问封装在try/except-KeyError子句中以返回默认值(正如Ethan所提到的,可以选择将其封装在您自己的函数/方法中)。这里值得注意的是,如果将其用于序列化/反序列化,请序列化此属性的
name
属性,因此使用
Build.debug.name
而不是
str(Build.debug)
以使这种查找工作(否则它会尝试在反序列化端查找不存在的
Build.debug
。@Dragonborn调用
Build('debug')将不起作用
。类构造函数必须接受该值,即本例中的
200
400
。要传递名称,必须使用方括号,正如答案所述。使用Python 3.6.6,我无法重现此行为。我想您可能在测试时犯了错误(我知道我第一次检查此项时就犯了错误)。如果您意外地在每个元素后放置了一个
(逗号)(就像元素是一个列表一样),那么它会将每个元素视为一个元组。(即
a='aaa',
实际上与
a=('aaa',)
)你是对的,这是我代码中的不同错误。我不知何故认为你需要在定义枚举时将
放在每行后面,将值转换为元组,如果你发现自己经常这样做的话:有没有办法覆盖
\uu getitem\uuuuu
或其他内置方法?有没有办法改变r编写
\uuu getitem\uuu
或其他内置方法?
MyEnum(('aaa',))
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
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')