我有一个基本的字典如下:

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。


当前回答

您应该在.datetime.now()方法上应用.strftime()方法,使其成为一个可序列化的方法。

这里有一个例子:

from datetime import datetime

time_dict = {'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')}
sample_dict = {'a': 1, 'b': 2}
sample_dict.update(time_dict)
sample_dict

输出:

Out[0]: {'a': 1, 'b': 2, 'time': '2017-10-31T15:16:30'}

(更新):

在Python3.7及以后版本中,你可以简单地使用.isoformat()方法:

from datetime import datetime

datetime.now().isoformat()

其他回答

我的解决方案(我认为不那么冗长):

def default(o):
    if type(o) is datetime.date or type(o) is datetime.datetime:
        return o.isoformat()

def jsondumps(o):
    return json.dumps(o, default=default)

然后使用jsondumps而不是json.dumps。它将打印:

>>> jsondumps({'today': datetime.date.today()})
'{"today": "2013-07-30"}'

如果你想,以后你可以添加其他特殊情况,通过一个简单的默认方法。例子:

def default(o):
    if type(o) is datetime.date or type(o) is datetime.datetime:
        return o.isoformat()
    if type(o) is decimal.Decimal:
        return float(o)

您应该在.datetime.now()方法上应用.strftime()方法,使其成为一个可序列化的方法。

这里有一个例子:

from datetime import datetime

time_dict = {'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')}
sample_dict = {'a': 1, 'b': 2}
sample_dict.update(time_dict)
sample_dict

输出:

Out[0]: {'a': 1, 'b': 2, 'time': '2017-10-31T15:16:30'}

(更新):

在Python3.7及以后版本中,你可以简单地使用.isoformat()方法:

from datetime import datetime

datetime.now().isoformat()

在其他答案的基础上,一个简单的解决方案基于只转换datetime的特定序列化器。Datetime和Datetime。将对象日期指定为字符串。

from datetime import date, datetime

def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))

As seen, the code just checks to find out if object is of class datetime.datetime or datetime.date, and then uses .isoformat() to produce a serialized version of it, according to ISO 8601 format, YYYY-MM-DDTHH:MM:SS (which is easily decoded by JavaScript). If more complex serialized representations are sought, other code could be used instead of str() (see other answers to this question for examples). The code ends by raising an exception, to deal with the case it is called with a non-serializable type.

这个json_serial函数可以这样使用:

from datetime import datetime
from json import dumps

print dumps(datetime.now(), default=json_serial)

详细说明如何将默认参数设置为json。可以在json模块文档的基本用法章节中找到dump作品。

我的快速和肮脏的JSON转储吃日期和一切:

json.dumps(my_dictionary, indent=4, sort_keys=True, default=str)

Default是一个应用于不可序列化对象的函数。 在这种情况下,它是str,所以它只是把所有它不知道的东西转换成字符串。这对于序列化很好,但在反序列化时就不太好了(因此是“快速和肮脏”),因为任何东西都可能在没有警告的情况下被字符串化,例如函数或numpy数组。

我在外部化django模型对象转储为JSON时也遇到了同样的问题。 以下是解决方法。

def externalize(model_obj):
  keys = model_obj._meta.get_all_field_names() 
  data = {}
  for key in keys:
    if key == 'date_time':
      date_time_obj = getattr(model_obj, key)
      data[key] = date_time_obj.strftime("%A %d. %B %Y")
    else:
      data[key] = getattr(model_obj, key)
  return data