我有一个基本的字典如下:
sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere
当我尝试做jsonify(sample)时,我得到:
TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable
我该怎么做才能使我的字典样本克服上面的错误呢?
注意:虽然它可能不相关,字典是从mongodb的记录检索中生成的,当我打印出str(sample['somedate'])时,输出是2012-08-08 21:46:24.862000。
您必须使用json.dumps的cls参数提供一个自定义编码器类。引用文件中的内容:
>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
... def default(self, obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... return json.JSONEncoder.default(self, obj)
...
>>> dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[', '2.0', ', ', '1.0', ']']
这里使用了复数作为示例,但是您也可以轻松地创建一个类来编码日期(除了我认为JSON对于日期有点模糊)
对于不需要或不想使用pymongo库的其他人。你可以用这个小片段轻松实现datetime JSON转换:
def default(obj):
"""Default JSON serializer."""
import calendar, datetime
if isinstance(obj, datetime.datetime):
if obj.utcoffset() is not None:
obj = obj - obj.utcoffset()
millis = int(
calendar.timegm(obj.timetuple()) * 1000 +
obj.microsecond / 1000
)
return millis
raise TypeError('Not sure how to serialize %s' % (obj,))
然后像这样使用它:
import datetime, json
print json.dumps(datetime.datetime.now(), default=default)
输出:
'1365091796124'
我可能不是百分百正确,
这是实现序列化的简单方法
#!/usr/bin/python
import datetime,json
sampledict = {}
sampledict['a'] = "some string"
sampledict['b'] = datetime.datetime.now()
print sampledict # output : {'a': 'some string', 'b': datetime.datetime(2017, 4, 15, 5, 15, 34, 652996)}
#print json.dumps(sampledict)
'''
output :
Traceback (most recent call last):
File "./jsonencodedecode.py", line 10, in <module>
print json.dumps(sampledict)
File "/usr/lib/python2.7/json/__init__.py", line 244, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2017, 4, 15, 5, 16, 17, 435706) is not JSON serializable
'''
sampledict['b'] = datetime.datetime.now().strftime("%B %d, %Y %H:%M %p")
afterdump = json.dumps(sampledict)
print afterdump #output : {"a": "some string", "b": "April 15, 2017 05:18 AM"}
print type(afterdump) #<type 'str'>
afterloads = json.loads(afterdump)
print afterloads # output : {u'a': u'some string', u'b': u'April 15, 2017 05:18 AM'}
print type(afterloads) # output :<type 'dict'>
我刚刚遇到了这个问题,我的解决方案是子类json。JSONEncoder:
from datetime import datetime
import json
class DateTimeEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return o.isoformat()
return json.JSONEncoder.default(self, o)
在你的调用中,做一些类似:json的事情。我从上面的答案之一得到的.isoformat()。
如果您正在使用python3.7,那么最好的解决方案是使用
datetime.isoformat()和
datetime.fromisoformat ();他们与天真的和
感知datetime对象:
#!/usr/bin/env python3.7
from datetime import datetime
from datetime import timezone
from datetime import timedelta
import json
def default(obj):
if isinstance(obj, datetime):
return { '_isoformat': obj.isoformat() }
raise TypeError('...')
def object_hook(obj):
_isoformat = obj.get('_isoformat')
if _isoformat is not None:
return datetime.fromisoformat(_isoformat)
return obj
if __name__ == '__main__':
#d = { 'now': datetime(2000, 1, 1) }
d = { 'now': datetime(2000, 1, 1, tzinfo=timezone(timedelta(hours=-8))) }
s = json.dumps(d, default=default)
print(s)
print(d == json.loads(s, object_hook=object_hook))
输出:
{"now": {"_isoformat": "2000-01-01T00:00:00-08:00"}}
True
如果您使用的是python3.6或以下版本,并且您只关心时间值(不是
),然后您可以使用datetime.timestamp()和
datetime.fromtimestamp()而不是;
如果您使用的是python3.6或以下版本,并且您确实关心时区,那么
你可以通过datetime获取。Tzinfo,但是您必须序列化这个字段
自己;类中添加另一个字段_tzinfo是最简单的方法
序列化的对象;
最后,要注意所有这些例子的精确性;