Python 处理 JSON 数据时,dumps
函数是经常用到的,当 JSON 数据中有特殊类型时,往往是比较头疼的,因为经常会报这样一个错误。
自定义编码类
1 | #!/usr/bin/env python |
1 | Traceback (most recent call last): |
原因在于 dumps
函数不知道如何处理 datetime
对象,默认情况下 json
模块使用 json.JSONEncoder
类来进行编码,此时我们需要自定义一下编码类。
1 | #!/usr/bin/env python |
定义编码类 CustomEncoder
并重写实例的 default
函数,对特殊类型进行处理,其余类型继续使用父类的解析。
1 | #!/usr/bin/env python |
最后整合起来,将类使用 cls
参数传入 dumps
函数即可。
使用 CustomEncoder
实例的 encode
函数可以对对象进行转码
1 | #!/usr/bin/env python |
在父类源码中,所有的编码逻辑都在 encode
函数中,default
只负责抛出 TypeError
异常,这就是文章开始报错的出处。
1 | #!/usr/bin/env python |
单分派装饰器处理对象
CustomEncoder
如果处理的对象种类很多的话,需要写多个 if elif else
来区分,这样并不是不行,但是不够优雅,不够 pythonic
根据对象的类型不同,而做出不同的处理。刚好有个装饰器可以做到这点,它就是单分派函数 functools.singledispatch
1 | #!/usr/bin/env python |
- 1 使用
@singledispatch
装饰encode
函数,是他处理默认类型。同时给他添加一个装饰器构造函数变量。 - 2 `@encode.register()` 是一个装饰器构造函数,接收需要处理的对象类型作为参数。用它装饰的函数不需要名字,_ 代替即可。
最后提一点,json
也可以在命令行中使用
1 | $ echo '{"json": "obj"}' | python -m json.tool |