Python-如何克服“ datetime.datetime无法JSON序列化”?

发布于 2021-02-02 23:19:50

我有一个基本的命令,如下所示:

sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere

当我尝试做时,jsonify(sample)我得到:

TypeError: datetime.datetime(2020, 8, 8, 21, 46, 24, 862000) is not JSON serializable

我该怎么做才能使我的词典示例可以克服上述错误?

注意:虽然可能不相关,但字典是从mongodb中检索记录生成的,在我打印输出时str(sample['somedate']),输出为2020-08-08 21:46:24.862000。

关注者
0
被浏览
58
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    原始答案适应了MongoDB“日期”字段表示为:

    {"$date": 1506816000000}

    如果你希望使用通用的Python解决方案序列化为datetimejson,请查看@jjmontes的答案以获取无需依赖项的快速解决方案。

    当你使用mongoengine(每个注释)并且pymongo是一个依赖项时,pymongo具有内置的实用程序来帮助json序列化:http ://api.mongodb.org/python/1.10.1/api/bson/json_util.html

    用法示例(序列化):

    from bson import json_util
    import json
    
    json.dumps(anObject, default=json_util.default)
    

    用法示例(反序列化):

    json.loads(aJsonString, object_hook=json_util.object_hook)
    

    Django

    Django提供了本机DjangoJSONEncoder序列化程序,可以正确处理这种情况。

    参见https://docs.djangoproject.com/en/dev/topics/serialization/#djangojsonencoder

    from django.core.serializers.json import DjangoJSONEncoder
    
    return json.dumps(
      item,
      sort_keys=True,
      indent=1,
      cls=DjangoJSONEncoder
    )
    

    我注意到DjangoJSONEncoder和使用这样的自定义之间的一个区别default:

    import datetime
    import json
    
    def default(o):
        if isinstance(o, (datetime.date, datetime.datetime)):
            return o.isoformat()
    
    return json.dumps(
      item,
      sort_keys=True,
      indent=1,
      default=default
    )
    
    

    是Django剥离了一些数据:

     "last_login": "2018-08-03T10:51:42.990", # DjangoJSONEncoder 
     "last_login": "2018-08-03T10:51:42.990239", # default
    

    因此,在某些情况下,你可能需要注意这一点。



  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    基于其他答案,这是一个基于特定序列化器的简单解决方案,该序列化器仅将datetime.datetime和转换datetime.date为字符串。

    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))
    

    如图所示,代码仅检查对象是否属于datetime.datetime或类datetime.date,然后.isoformat()根据ISO 8601格式YYYY-MM-DDTHH:MM:SS生成对象的序列化版本(可以很容易地用JavaScript解码) )。如果寻求更复杂的序列化表示形式,则可以使用其他代码代替str()(有关示例,请参见此问题的其他答案)。该代码以引发异常来结束,以处理使用非序列化类型调用该异常的情况。

    json_serial函数可以按以下方式使用:

    from datetime import datetime
    from json import dumps
    
    print dumps(datetime.now(), default=json_serial)
    


  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。


    我的快速且的JSON转储会吃掉日期和所有东西:

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

知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看