Back

扩展Python Json Encoder

Python默认的json模块序列化并不是很全面,只能序列化基本的数据类型, 像一些时间格式或者自定义类型都不能序列化,所以在有些时候需要扩展json模块的json encoder

扩展

import datetime as dt
import decimal
import json
import enum
from collections.abc import Iterator

class ExtendedEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, dt.datetime):
            return o.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(o, dt.date):
            return o.strftime('%Y-%m-%d')
        elif isinstance(o, decimal.Decimal):
            return float(o)
        elif isinstance(o, Iterator):
            return list(o)
        elif isinstance(o, enum.Enum):
            return o.value
        return json.JSONEncoder.default(self, o)

使用场景

  • 日常格式化

    例如对于日期格式的格式化

    import datetime as dt
    
    now = dt.datetime.now()
    

    对于now如果使用json.dumps(t_now)便会触发TypeError: Object of type datetime is not JSON serializable 使用扩展的Encoder

     >>> json.dumps(now, cls=ExtendedEncoder)
     '2018-04-09 23:04:49'
    
  • Flask

    修改flask类的json_encoder

    from flask import Flask as _Flask
    class QuizFlask(_Flask):
      """
      自定义flask
      """
    
      json_encoder = ExtendedEncoder
    
      def make_response(self, rv):
          if rv is None:
              rv = dict()
    
          if isinstance(rv, Iterator):
              rv = list(rv)
    
          return super(QuizFlask, self).make_response(rv)
    
  • Tortoise-orm

    模型jsonfield的encoder

    import json
      
    from tortoise import fields
    from tortoise.models import Model
      
    __all__ = ['OurModel']
      
    class OurModel(Model):
        """示例model"""
      
        id = fields.IntField(pk=True)
        cat_ids = fields.JSONField(
            encoder=ExtendedEncoder, decoder=json.decoder
        ) 	# JsonField的encoder
      
    
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy