第六章 : 对象的序列化

1.自定义对象的序列化出错

import json

class People(object):
    def __init__(self, name, age, job):
        self.name = name
        self.age = age
        self.job = job


if __name__ == "__main__":
    p = People('lily',18,'IT')
    print(json.dumps(p))
##########################
# TypeError: Object of type 'People' is not JSON serializable

dumps()中要传入是字典类型或列表类型


2.改写

通过obj.__dict__实现

import json

class People(object):
    def __init__(self, name, age, job):
        self.name = name
        self.age = age
        self.job = job


if __name__ == "__main__":
    p = People('lily',18,'IT')
    res = json.dumps(p, default=lambda o:o.__dict__)
    print(res)
 ################
 # '{"name": "lily", "age": 18, "job": "IT"}'

3.改写

通过把自定义对象变为字典实现

import json

class People(object):
    def __init__(self, name, age, job):
        self.name = name
        self.age = age
        self.job = job

    def keys(self):
        return ('name','age','job')

    def __getitem__(self, item):
        return getattr(self, item)


if __name__ == "__main__":
    p = People('lily',18,'IT')
    res = json.dumps(dict(p))
    print(res)

4.改写flask中的jsonify

class JSONEncoder(_json.JSONEncoder):
    """The default Flask JSON encoder.  This one extends the default simplejson
    encoder by also supporting ``datetime`` objects, ``UUID`` as well as
    ``Markup`` objects which are serialized as RFC 822 datetime strings (same
    as the HTTP date format).  In order to support more data types override the
    :meth:`default` method.
    """

    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 :exc:`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)
                return JSONEncoder.default(self, o)
        """
        if isinstance(o, datetime):
            return http_date(o.utctimetuple())
        if isinstance(o, date):
            return http_date(o.timetuple())
        if isinstance(o, uuid.UUID):
            return str(o)
        if hasattr(o, '__html__'):
            return text_type(o.__html__())
        return _json.JSONEncoder.default(self, o)

如果jsonify(*) ,*不能序列化,那么就会进入default方法中,递归调用,如果default方法中不能把*转化为可序列化的对象,就会抛出错误。

app/libs/new_flask.py
from flask import Flask as _Flask
from flask.json import JSONEncoder as _JSONEncoder

class JSONEncoder(_JSONEncoder):
        def default(self, o):
        if hasattr(o, 'keys'):
            return dict(o)
        if isinstance(o, date):
            return o.strftime("%Y-%m-%d")
        raise ServerError()



class Flask(_Flask):
    json_encoder = JSONEncoder
app/models/user.py
class User(Base):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    email = db.Column(db.String(32), nullable=False, unique=True)
    nickname = db.Column(db.String(16), nullable=False, unique=True)
    _password = db.Column("password", db.String(128), nullable=False)

    def __repr__(self):
        return "<nickname %r>" % self.nickname

    def keys(self):
        return ("email","nickname", "create_time")

    def __getitem__(self, item):
        return getattr(self, item)
    ...
    ...

猜你喜欢

转载自blog.csdn.net/lilied001/article/details/80848415