将枚举成员序列化为JSON [英] Serialising an Enum member to JSON

查看:214
本文介绍了将枚举成员序列化为JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将Python 枚举成员序列化为JSON,以便将结果JSON反序列化为Python对象?

How do I serialise a Python Enum member to JSON, so that I can deserialise the resulting JSON back into a Python object?

例如,此代码:

from enum import Enum    
import json

class Status(Enum):
    success = 0

json.dumps(Status.success)

导致错误:

TypeError: <Status.success: 0> is not JSON serializable

我该如何避免?

推荐答案

如果要将任意的 enum.Enum 成员编码为JSON,然后将
解码为相同的枚举成员(而不仅仅是枚举成员的属性),您可以通过编写自定义 JSONEncoder 类,并将解码功能作为 object_hook 参数 json.load() json.loads()

If you want to encode an arbitrary enum.Enum member to JSON and then decode it as the same enum member (rather than simply the enum member's value attribute), you can do so by writing a custom JSONEncoder class, and a decoding function to pass as the object_hook argument to json.load() or json.loads():

PUBLIC_ENUMS = {
    'Status': Status,
    # ...
}

class EnumEncoder(json.JSONEncoder):
    def default(self, obj):
        if type(obj) in PUBLIC_ENUMS.values():
            return {"__enum__": str(obj)}
        return json.JSONEncoder.default(self, obj)

def as_enum(d):
    if "__enum__" in d:
        name, member = d["__enum__"].split(".")
        return getattr(PUBLIC_ENUMS[name], member)
    else:
        return d

as_enum 函数依赖于使用 EnumEncoder 编码的JSON,或者与其相同的行为。

The as_enum function relies on the JSON having been encoded using EnumEncoder, or something which behaves identically to it.

PUBLIC_ENUMS 的成员的限制是必要的,以避免使用恶意制作的文本,例如,将主叫代码篡改为保存私人信息(例如应用程序使用的秘密密钥)到一个不相关的数据库字段,然后可以从中显示它(请参阅 http:/ /chat.stackoverflow.com/transcript/message/35999686#35999686 )。

The restriction to members of PUBLIC_ENUMS is necessary to avoid a maliciously crafted text being used to, for example, trick calling code into saving private information (e.g. a secret key used by the application) to an unrelated database field, from where it could then be exposed (see http://chat.stackoverflow.com/transcript/message/35999686#35999686).

使用示例:

>>> data = {
...     "action": "frobnicate",
...     "status": Status.success
... }
>>> text = json.dumps(data, cls=EnumEncoder)
>>> text
'{"status": {"__enum__": "Status.success"}, "action": "frobnicate"}'
>>> json.loads(text, object_hook=as_enum)
{'status': <Status.success: 0>, 'action': 'frobnicate'}

这篇关于将枚举成员序列化为JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆