自定义json模块的序列化
2019-08-12 11:13 美丽的名字 阅读(413) 评论(0) 收藏 举报官方的json模块只能对Python支持的常见数据结构进行序列化,无法支持对于数据结构中存在自定义对象的数据的序列化。
样例数据:
{
"key1": 123,
"key2": datatime.now()
}
对于上面的数据,如果用官方的json模块无法对datatime.now()这个对象进行序列化,所以需要对官方json模块进行定制以支持对该对象的序列化。
json.__init__.py
# cached encoder
if (not skipkeys and ensure_ascii and
check_circular and allow_nan and
cls is None and indent is None and separators is None and
default is None and not sort_keys and not kw):
return _default_encoder.encode(obj)
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)
json.dumps方法中定义了默认的encoder就是JSONEncoder,在对数据进行dumps的时候会默认使用这个encoder,我们可以对它进行自定义。
json.encoder.py
通过default方法的描述,我们可以了解想要通过自定义实现对其他对象的序列化需要按照encode方法重写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(f'Object of type {o.__class__.__name__} '
f'is not JSON serializable')
def encode(self, o):
"""Return a JSON string representation of a Python data structure.
>>> from json.encoder import JSONEncoder
>>> JSONEncoder().encode({"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'
"""
# This is for extremely simple cases and benchmarks.
if isinstance(o, str):
if self.ensure_ascii:
return encode_basestring_ascii(o)
else:
return encode_basestring(o)
# This doesn't pass the iterator directly to ''.join() because the
# exceptions aren't as detailed. The list call should be roughly
# equivalent to the PySequence_Fast that ''.join() would do.
chunks = self.iterencode(o, _one_shot=True)
if not isinstance(chunks, (list, tuple)):
chunks = list(chunks)
return ''.join(chunks)
自定义JsonCustomEncoder类,重写父类json.JSONEncoder的default方法:
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(o, date):
return o.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, o)
d = {
"key1": 123,
"key2": datetime.now(),
}
ds = json.dumps(d, cls=JsonCustomEncoder)
print(ds)
浙公网安备 33010602011771号