python进阶

python 解决datetime、date、decimal等类

2019-08-22  本文已影响0人  落羽归尘

背景

在python中,我们使用json.dumps或者tornado的self.write等有关json序列化时,会遇到这些错误:

解决办法:

import json
from decimal import Decimal
from datetime import datetime,date

class DateEncoder(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")
        elif isinstance(o, Decimal):
            return float(o)
        else:
            return json.JSONEncoder.default(self, o)


d = {"a":Decimal(10),"time":datetime.now(),"c":4}

str_ = json.dumps(d, cls=DateEncoder)
print(str_)

tornado中经常也会碰到这种问题,解决办法当然是重载write方法了,如下:

class DateEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime.datetime):
            return o.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(o, datetime.date):
            return o.strftime("%Y-%m-%d")
        elif isinstance(o, Decimal):
            return float(o)
        else:
            return json.JSONEncoder.default(self, o)


class TestHandler(RequestHandler):
    def write(self, chunk):
        if self._finished:
            raise RuntimeError("Cannot write() after finish()")
        if not isinstance(chunk, (bytes, unicode_type, dict)):
            message = "write() only accepts bytes, unicode, and dict objects"
            if isinstance(chunk, list):
                message += ". Lists not accepted for security reasons; see " + \
                           "http://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.write"
            raise TypeError(message)
        if isinstance(chunk, dict):
            # 返回数据库数据中存在datetime、date,decimal格式,原write会报错
            chunk = json.dumps(chunk, cls=DateEncoder).replace("</", "<\\/")
            self.set_header("Content-Type", "application/json; charset=UTF-8")
        chunk = escape.utf8(chunk)
        self._write_buffer.append(chunk)
上一篇下一篇

猜你喜欢

热点阅读