将 Python 枚举编码为 JSON

2024-03-11

我有一本字典,其中一些键是 Enum 实例(enum.Enum 的子类)。我正在尝试使用自定义 JSON 编码器类将字典编码为 JSON 字符串,如下所示文档 https://docs.python.org/3/library/json.html#json.JSONEncoder。我想要的只是让输出的 JSON 中的键是 Enum 名称的字符串。例如{ TestEnum.one : somevalue }将被编码为{ "one" : somevalue }.

我编写了一个简单的测试用例,如下所示,我在干净的 virtualenv 中对其进行了测试:

import json

from enum import Enum

class TestEnum(Enum):
    one = "first"
    two = "second"
    three = "third"

class TestEncoder(json.JSONEncoder):
    """ Custom encoder class """

    def default(self, obj):

        print("Default method called!")

        if isinstance(obj, TestEnum):
            print("Seen TestEnum!")
            return obj.name

        return json.JSONEncoder.default(self, obj)

def encode_enum(obj):
    """ Custom encoder method """

    if isinstance(obj, TestEnum):
        return obj.name
    else:
        raise TypeError("Don't know how to decode this")

if __name__ == "__main__":

    test = {TestEnum.one : "This",
            TestEnum.two : "should",
            TestEnum.three : "work!"}

    # Test dumps with Encoder method
    #print("Test with encoder method:")
    #result = json.dumps(test, default=encode_enum)
    #print(result)

    # Test dumps with Encoder Class
    print("Test with encoder class:")
    result = json.dumps(test, cls=TestEncoder)
    print(result)

我无法成功对字典进行编码(使用 Python 3.6.1)。我不断地得到TypeError: keys must be a string错误和我的自定义编码器实例的默认方法(通过提供cls的论点json.dumps方法)似乎从未被调用过?我还尝试通过提供自定义编码方法default的论点json.dumps方法,但这又永远不会被触发。

我见过涉及 IntEnum 类的解决方案,但我需要 Enum 的值是字符串。我也见过这个答案 https://stackoverflow.com/questions/21606049/json-encode-decode-gtk-enums其中讨论了与从另一个类继承的枚举相关的问题。但是,我的枚举仅继承自基本 enum.Enum 类并正确响应isinstance calls?

自定义类和方法都会生成一个TypeError当供应给json.dumps方法。典型输出如下所示:

$ python3 enum_test.py

Test with encoder class
Traceback (most recent call last):
  File "enum_test.py", line 59, in <module>
    result = json.dumps(test, cls=TestEncoder)
  File "/usr/lib64/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/lib64/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib64/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
TypeError: keys must be a string

我认为问题在于encodeJSONEncoder 类的方法假设它知道如何序列化 Enum 类(因为其中的 if 语句之一)iterencode方法被触发),因此永远不会调用自定义默认方法并导致无法序列化枚举?

任何帮助将不胜感激!


这是一个老问题了。但没有人给出这个非常简单的答案。

您只需要从 str 继承您的 Enum 即可。

import json

from enum import Enum

class TestEnum(str, Enum):
    one = "first"
    two = "second"
    three = "third"

test = {TestEnum.one : "This",
        TestEnum.two : "should",
        TestEnum.three : "work!"}

print(json.dumps(test))

outputs:

{"first": "This", "second": "should", "third": "work!"}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Python 枚举编码为 JSON 的相关文章

随机推荐