修改json源码支持datetime序列化

修改json源码支持datetime序列化

import json
import datetime now = datetime.datetime.today() json.dumps(now)

抛出异常

TypeError: Object of type 'datetime' is not JSON serializable

查看dumps源码发现cls是起作用的方法

    if cls is None:
cls = JSONEncoder
return cls(
skipkeys=skipkeys, ensure_ascii=ensure_ascii,
check_circular=check_circular, allow_nan=allow_nan, indent=indent,
separators=separators, default=default, sort_keys=sort_keys,
**kw).encode(obj)

最后在JSONEncoder找到抛出异常的位置,我们可以拦截datetime抛出的异常进行处理

 可以看到json支持这些数据类型,要是不是这些类型的会进入defualt方法
+-------------------+---------------+
| Python | JSON |
+===================+===============+
| dict | object |
+-------------------+---------------+
| list, tuple | array |
+-------------------+---------------+
| str | string |
+-------------------+---------------+
| int, float | number |
+-------------------+---------------+
| True | true |
+-------------------+---------------+
| False | false |
+-------------------+---------------+
| None | null |
+-------------------+---------------+

通过源码的注释大概知道它允许通过重写方法的形式,改写default方法,自定义

    def default(self, o):
"""Implement this method in a subclass such that it returns
a serializable object for ``o``, or calls the base implementation
(to raise a ``TypeError``). For example, to support arbitrary iterators, you could
implement default like this:: def default(self, o):
try:
iterable = iter(o)
except TypeError:
pass
else:
return list(iterable)
# Let the base class default method raise the TypeError
return JSONEncoder.default(self, o) """
raise TypeError("Object of type '%s' is not JSON serializable" %
o.__class__.__name__)

执行重写操作

import json
import datetime class zxJsonClass(json.JSONEncoder):
def default(self, o):
if isinstance(o,datetime.datetime):#如果是datetime类型,转成json可以支持的类型
return o.strftime('%Y-%m-%d')
else:
super().default(self,o) now = datetime.datetime.today()
print(json.dumps(now, cls=zxJsonClass))

改写成功

import json
import datetime class zxJsonClass(json.JSONEncoder):
def default(self, o):
if isinstance(o,datetime.datetime):#如果是datetime类型,转成json可以支持的类型
return o.strftime('%Y-%m-%d')
else:
super().default(self,o) now = datetime.datetime.today()
print(json.dumps(now, cls=zxJsonClass)) "2019-10-23"

小知识点

import json

zx="圣诞树zx"
zx2 = {"h":"l"}
print(zx)
print(zx2)
print(json.dumps(zx,ensure_ascii=False))
print(json.dumps(zx2,ensure_ascii=False))

打印json字符串,会带双引号,但是普通字符串不显示,字典的单,双引号

json这样改是为了更好的区分json格式的字符串

上一篇:【C语言】中的stdbool.h头文件


下一篇:Hadoop学习之旅三:MapReduce