是否可以在没有将编码器传递给json.dumps()的情况下在json中转储枚举?

Axe*_*rja 7 python enums json python-2.7

我可以通过以下示例总结我的问题:

from enum import Enum
import json

class FooBarType(Enum):
    standard = 0
    foo = 1
    bar = 2

dict = {'name': 'test', 'value': 'test', 'type': FooBarType.foo}

json.dumps(dict)

TypeError: <FooBarType.foo: 1> is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

我收到类型错误,因为枚举不是JSON可序列化的.

我主要是实现a JsonEncoder并将其添加到json.dumps()调用中但我无法更改json.dumps()调用的行.

所以,我的问题是: 是否可以在不通过编码器的情况下在json中转储枚举json.dumps(),而是通过在FooBarType枚举中添加类方法?

我希望提取以下json:

{'name': 'test', 'value': 'test', 'type': 'foo'}
Run Code Online (Sandbox Code Playgroud)

要么

{'name': 'test', 'value': 'test', 'type': 1}
Run Code Online (Sandbox Code Playgroud)

gil*_*red 16

尝试:

from enum import Enum

# class StrEnum(str, Enum):
#     """Enum where members are also (and must be) strs"""

class Color(str, Enum):
    RED = 'red'
    GREEN = 'green'
    BLUE = 'blue'


data = [
    {
        'name': 'car',
        'color': Color.RED,
    },
    {
        'name': 'dog',
        'color': Color.BLUE,
    },
]

import json
print(json.dumps(data))
Run Code Online (Sandbox Code Playgroud)

结果:

[
    {
        "name": "car",
        "color": "red"
    },
    {
        "name": "dog",
        "color": "blue"
    }
]
Run Code Online (Sandbox Code Playgroud)

  • 这应该是答案! (2认同)
  • 这种方法可能会产生意想不到的副作用;参见例如/sf/ask/4573774481/ (2认同)

Eth*_*man 5

Enum遗憾的是, JSON没有直接支持。

最接近的自动支持是使用IntEnum(它enum34也支持),然后json会将你的enums视为ints;当然,解码它们会给你一个int支持,但在不指定编码器/解码器的情况下也一样好。


Nil*_*ehn 3

更新:请阅读@gil9red的答案,我认为它比我的更好!

我认为没有一个好的方法可以做到这一点,并且您将失去枚举的功能。

最简单的选择:不要子类化 Enum:

class FooBarType:
    standard = 0
    foo = 1
    bar = 2

dict = {'type': FooBarType.foo}
json.dumps(dict)
Run Code Online (Sandbox Code Playgroud)

你还可以做什么:

class EnumIntValue(int):
    def __new__(cls, name, value):
        c = int.__new__(cls, int(value))
        c.name = name
        return c
    def __repr__(self):
        return self.name
    def __str__(self):
        return self.name

class FooBarType:
    standard = EnumIntValue('standard',0)
    foo = EnumIntValue('foo',0)
    bar = EnumIntValue('bar',2)

dict = {'type': FooBarType.foo}
json.dumps(dict)
Run Code Online (Sandbox Code Playgroud)

这实际上会给你

{"type": foo}
Run Code Online (Sandbox Code Playgroud)

因此并不是真正有效的 json,但您可以使用它来满足您的需求!