我正在使用 python 对其中带有时间戳的 OrderedDict 进行编码,但我遇到了问题。我尝试编码的数据如下所示:
OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)), ('b', 'b'), ('c', 'c'), ('d', 'd')])
我希望这是 json 编码和解码以获得完全相同的数据。
为了直接编码时间戳,而不更改为 ISO 或 Unix 时间,我使用了 bson 的 json_util 接口(interface),如下所示。它工作正常。
json.dumps(str, default=json_util.default)
json.loads(jsonstr, object_hook=json_util.object_hook)
为了获得 OrderedDict,我使用了 object_pairs_hook,它也有效:
json.loads(x, object_pairs_hook=OrderedDict)
但是,当一起使用时,两者会相互混淆,结果格式不正确(因为 bson 接口(interface)正在为时间戳创建一个额外的字典)。
json.loads(jsonstr, object_hook=json_util.object_hook, object_pairs_hook=OrderedDict)
这个查询最终得到这个:
OrderedDict([(u'a', OrderedDict([(u'$date', 1434383934884L)])), (u'b', u'b'), (u'c', u'c'), (u'd', u'd')])
时间戳未正确解析。关于如何正确执行此操作的任何建议? (泡菜可能是一个方向,但我首先寻求其他解决方案)。
最佳答案
您可以定义自己的解码器来处理日期时间和 OrderedDict,并在 object_pairs_hook
中使用它。为了方便和测试,我还定义了自己的编码器,但您可以自由使用已有的编码器。
#!/usr/bin/env python3
import json
import datetime
from collections import OrderedDict
# Test dictionary
a = OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)),
('b', 'b'), ('c', 'c'), ('d', 'd')])
print(a)
# Encoder for datetime
def encoder(obj):
if type(obj) is datetime.datetime:
return {'$date$': obj.timestamp()}
raise TypeError
# Encode
s = json.dumps(a, default=encoder)
print("JSON:", s)
# Decoder for OrderedDict and datetime
def decoder(obj):
if len(obj) == 1 and len(obj[0]) == 2 and obj[0][0] == '$date$':
return datetime.datetime.fromtimestamp(obj[0][1])
else:
return OrderedDict(obj)
# Decode
b = json.loads(s, object_pairs_hook=decoder)
print(b)
# Compare
print("Comparing:", a == b)
这将打印:
OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)), ('b', 'b'), ('c', 'c'), ('d', 'd')])
JSON: {"a": {"$date$": 1434409134.884}, "b": "b", "c": "c", "d": "d"}
OrderedDict([('a', datetime.datetime(2015, 6, 15, 15, 58, 54, 884000)), ('b', 'b'), ('c', 'c'), ('d', 'd')])
Comparing: True
关于python - 将 json 与 OrderedDict 和 Datetime 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30856538/