当键是非平凡的对象时,如何将Python字典转储为JSON? [英] How to dump a Python dictionary to JSON when keys are non-trivial objects?
问题描述
import datetime, json
x = {'alpha': {datetime.date.today(): 'abcde'}}
print json.dumps(x)
上面的代码以TypeError
失败,因为JSON对象的键必须是字符串. json.dumps
函数具有一个称为default的参数,当JSON对象的 value 引发TypeError
时将调用该参数,但对于 key .解决此问题的最优雅的方法是什么?
您可以扩展json.JSONEncoder来创建自己的编码器,该编码器可以处理datetime.datetime对象(或您想要的任何类型的对象),例如创建字符串的方法,可以将其复制为新的datetime.datetime实例.我相信它应该像在datetime.datetime实例上具有json.JSONEncoder调用repr()一样简单.
json模块检查需要编码的每个值的类型,默认情况下,它仅知道如何处理字典,列表,元组,str,unicode对象,int,long,float,boolean和none:-)>
对您来说也很重要的是JSONEncoder的skipkeys参数.
阅读您的评论后,我得出结论,要让JSONEncoder使用自定义函数对字典的键进行编码,没有简单的解决方案.如果您有兴趣,可以查看源代码和方法iterencode(),该方法调用_iterencode(),该方法调用_iterencode_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"}'.为了美观起见,请将其包装在一个函数中:-)
import datetime, json
x = {'alpha': {datetime.date.today(): 'abcde'}}
print json.dumps(x)
The above code fails with a TypeError
since keys of JSON objects need to be strings. The json.dumps
function has a parameter called default that is called when the value of a JSON object raises a TypeError
, but there seems to be no way to do this for the key. What is the most elegant way to work around this?
You can extend json.JSONEncoder to create your own encoder which will be able to deal with datetime.datetime objects (or objects of any type you desire) in such a way that a string is created which can be reproduced as a new datetime.datetime instance. I believe it should be as simple as having json.JSONEncoder call repr() on your datetime.datetime instances.
The procedure on how to do so is described in the json module docs.
The json module checks the type of each value it needs to encode and by default it only knows how to handle dicts, lists, tuples, strs, unicode objects, int, long, float, boolean and none :-)
Also of importance for you might be the skipkeys argument to the JSONEncoder.
After reading your comments I have concluded that there is no easy solution to have JSONEncoder encode the keys of dictionaries with a custom function. If you are interested you can look at the source and the methods iterencode() which calls _iterencode() which calls _iterencode_dict() which is where the type error gets raised.
Easiest for you would be to create a new dict with isoformatted keys like this:
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)
Which returns '{"2010-09-15T23:24:36.169710": "foo", "2010-09-15T23:24:36.169723": "bar"}'. For niceties, wrap it in a function :-)
这篇关于当键是非平凡的对象时,如何将Python字典转储为JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!