Py学习  »  Python

每天一个Python小技巧(3)

米洛丶 • 2 年前 • 202 次点击  
阅读 33

每天一个Python小技巧(3)

每天一个Python小技巧(3)之JSON序列化

大家好,这里是米洛,一个想和大家一起分享测试开发相关的技术,面试经验和成长经历的博主!

欢迎大家关注我的公众号: 测试开发坑货


几乎每个人都用过json序列化Python对象,比如:

import json
data = {"code": 101, "status": True}
result = json.dumps(data)
复制代码

大家应该也都知道,要想中文被正常解析,还得传入这样的参数:

result = json.dumps(data, ensure_ascii=False)
复制代码

那么你知道,json.dumps方法还有很多其他参数等你去研究吗?

故事

榜一大哥,他最近在研究MongoDB,他使用pymongo,查出来了一个mongo数据对象,在Python中的值是这样的:

result = {
    "_id": ObjectId("60f7ff90d013bd74e50c5a95"),
    "name": "hehe",
    "student": False
}
复制代码

榜一大哥想着,能把这个数据给写到txt里,于是他想起来json.dumps先把数据序列化,再操作文件write方法写入数据。

print(json.dumps(result))
复制代码

可是现实给了他一记重拳!

因为MongoDB默认的_id字段是Object类型,在json中没有与之对应的数据。

至于为什么其他数据能对应,因为他们从Python到JSON有对应数据转换规则:

其实不止是ObjectId,我们常用的datetime对象也是如此。

小技巧

解决问题很容易,既然没有规则,那咱们就创造规则

ObjectId实际上是一串字符串,而datetime我们常用字符串如2001-02-01 11:11:11这样的字符串表示。

dumps方法为我们提供了自定义类,专门解析表里面没有的(或者我们自定义的)数据类型。

class MyEncoder(JSONEncoder):

    def default(self, o):
        if isinstance(o, datetime):
            return o.strftime("%Y-%m-%d %H:%M:%S")
        if isinstance(o, ObjectId):
            return o.__str__()
        return JSONEncoder.default(self, o)
复制代码

我们继承json.JSONEncoder类,重写default方法,如果数据类型是datetime,我们则调用strftime方法,让它变成字符串,而对于ObjectId,我们直接将之转为str即可。

修改后的完整代码:

import json
from datetime import datetime
from json import JSONEncoder

from bson import ObjectId


class MyEncoder(JSONEncoder):

    def default(self, o):
        if isinstance(o, datetime):
            return o.strftime("%Y-%m-%d %H:%M:%S")
        if isinstance(o, ObjectId):
            return o.__str__()
        return JSONEncoder.default(self, o)

result = {
    "_id": ObjectId(),
    "name": "hehe",
    "create_time": datetime.now(),
    "student": False,
}

print(json.dumps(result, cls=MyEncoder))
复制代码

编写好类以后,把类传递给cls参数就可以达到目的。

肥肠好用!!!

这个是送的

榜一大哥觉得一行显示不好看,想格式化一下该怎么做呢?

print(json.dumps(result, cls=MyEncoder, indent=4))
复制代码

只需要加一个indent参数即可,一般可以用2或者4,看看符不符合榜一大哥的口味。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/117470
 
202 次点击