当键是非平凡的对象时,如何将Python字典转储为JSON? [英] How to dump a Python dictionary to JSON when keys are non-trivial objects?

查看:104
本文介绍了当键是非平凡的对象时,如何将Python字典转储为JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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模块文档.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆