修改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格式的字符串