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

猜你喜欢

转载自www.cnblogs.com/zx125/p/11728366.html
今日推荐