如何在python中将IntEnum从enum34序列化为json?

2024-10-03 23:25:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用enum34包,并设法以自定义格式存储将Enum子类化为json的对象。但是,我有一个对象实例使用了相当多的子类IntEnum,我的自定义JSONEncoder似乎没有正确地获取它。在

我最后的办法是将其转换为Enum并相应地重构所有相关的代码。IntEnum的优点是我可以进行位操作/测试。在

下面是一个例子和自定义编码器。请注意,Enum是有效的,但我假设IntEnum在传递给默认函数之前被捕获。在

class TimeMode(Enum):
    NTSC = 0
    PAL = 1
    Film = 2

class UiFlags(IntEnum):
    Empty = 0
    Clear = 0
    Checked = 1
    Selected = 2
    Shared = 8

class CObjectsEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, IntEnum):
            return {'__class__': o.__class__.__name__,
                    '__value__': (o.value,)}
        if isinstance(o, Enum):
            return {'__class__': o.__class__.__name__,
                    '__value__': (o.value,)}
    return json.JSONEncoder.default(self, o)

time_mode = TimeMode.NTSC
ui_flags = UiFlags.Checked
CObjectsEncoder().encode(time_mode)   
CObjectsEncoder().encode(ui_flags)

结果:

^{pr2}$

有没有办法让我得到同样的结果?我假设它在前面被转换成str,就像它是一个int。我怎样才能让编码器接收IntEnum呢?在


Tags: 对象jsonreturnvalueenum编码器子类class
2条回答

这里的问题是isinstance(ui_flags, int)是真的,这意味着对整数使用了标准编码。您的自定义编码器永远不会被调用,因为内置编码器“知道”如何处理整数:

>>> isinstance(UiFlags.Checked, IntEnum)
True
>>> isinstance(UiFlags.Checked, int)
True

JSONEncoder级别有解决方法;您可以对结构进行预处理:

^{pr2}$

并将其应用到要编码的数据上,然后再将其应用到JSON编码之前:

json.dumps(map_intenum(data), cls=CObjectsEncoder)

下一步是重写JSONEncoder.iterencode()并在编码之前应用转换:

class CObjectsEncoder(json.JSONEncoder):
    def iterencode(self, o, _one_shot=False):
        o = map_intenum(o)
        return super(CObjectsEncoder, self).iterencode(o, _one_shot)
    def default(self, o):
        if isinstance(o, Enum):
            return {'__class__': o.__class__.__name__,
                    '__value__': (o.value,)}
        return super(CObjectsEncoder, self).default(o)

我通过在IntEnum类上实现__str__来解决这个问题:

class UiFlags(IntEnum):
    Empty = 0
    Clear = 0

    def __str__(self):
        return str(self.value)

json.dumps({'empty': UiFlags.Empty, 'clear': UiFlags.Clear})
# {"empty": 0, "clear": 1}

相关问题 更多 >