import datetime, json
x = {'alpha': {datetime.date.today(): 'abcde'}}
print json.dumps(x)
由于JSON对象的键需要是字符串,因此上面的代码失败并带有TypeError
。 json.dumps
函数有一个名为default的参数,当JSON对象的值引发TypeError
时会调用该参数,但似乎没有办法为< EM>键的。解决这个问题最优雅的方法是什么?
答案 0 :(得分:5)
你可以扩展json.JSONEncoder来创建你自己的编码器,它能够处理datetime.datetime对象(或你想要的任何类型的对象),这样就可以创建一个可以作为一个新的字符串再现的字符串。 datetime.datetime实例。我相信它应该就像让你的datetime.datetime实例上的json.JSONEncoder调用repr()一样简单。
中介绍了如何执行此操作的步骤json模块检查它需要编码的每个值的类型,默认情况下它只知道如何处理dicts,lists,tuples,strs,unicode对象,int,long,float,boolean和none: - )
对你来说同样重要的可能是JSONEncoder的skipkeys参数。
在阅读完您的评论后,我得出结论,没有简单的解决方案让JSONEncoder使用自定义函数对字典键进行编码。如果您感兴趣,可以查看源和方法iterencode(),它调用_iterencode()调用_iterencode_dict(),这是引发类型错误的地方。
最简单的方法是使用isoformatted键创建一个新的dict:
import datetime, json
D = {datetime.datetime.now(): 'foo',
datetime.datetime.now(): 'bar'}
new_D = {}
for k,v in D.iteritems():
new_D[k.isoformat()] = v
json.dumps(new_D)
返回'{“2010-09-15T23:24:36.169710”:“foo”,“2010-09-15T23:24:36.169723”:“bar”}'。对于细节,请将其包装在一个函数中: - )
答案 1 :(得分:2)
http://jsonpickle.github.io/可能就是你想要的。面对类似问题时,我最终做了:
to_save = jsonpickle.encode(THE_THING, unpicklable=False, max_depth=4, make_refs=False)
答案 2 :(得分:0)
x = {'alpha': {datetime.date.today().strftime('%d-%m-%Y'): 'abcde'}}
答案 3 :(得分:0)
如果您确实需要这样做,可以对json.encoder进行猴子补丁:
from _json import encode_basestring_ascii # used when ensure_ascii=True (which is the default where you want everything to be ascii)
from _json import encode_basestring # used in any other case
def _patched_encode_basestring(o):
"""
Monkey-patching Python's json serializer so it can serialize keys that are not string!
You can monkey patch the ascii one the same way.
"""
if isinstance(o, MyClass):
return my_serialize(o)
return encode_basestring(o)
json.encoder.encode_basestring = _patched_encode_basestring