【发布时间】:2015-09-07 19:23:51
【问题描述】:
我正在使用 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)
结果:
'{"__class__": "TimeMode", "__value__": [0]}' # correct encoding
'UiFlags.Checked' # incorrect encoding
有没有办法让 IntEnum 获得相同的结果?我假设它像 int 一样被预先转换为 str 。如何让编码器获取 IntEnum?
【问题讨论】:
-
这里的问题是
isinstance(ui_flags, int)为真,这意味着使用了整数的标准编码。您的自定义编码器永远不会被调用,因为内置编码器“知道”如何处理整数。 -
有没有一种简单的方法可以在不编辑编码、迭代编码方法的情况下绕过这个问题?