Python中类的JSON序列化

这肯定是个老生常谈的问题,在此记录下。

在Python中,当在我们使用sqlalchemy.orm来对数据库对象进行存取,并将这些数据展现到前台页面时,我们就面临如何将Python中的类对象进行JSON序列化。

简单起见,我们从代码说起:

首先,我们定义一个用户类,用以存储用户信息

class User(object):
    def __init__(self, id, name, password):
        self.__id = id
        self.__name = name
        self.__password = password

    def __repr__(self):
        return "id is %s, name is %s, password is %s" % (self.__id, self.__name, self.__password)

    def get_name(self):
        return self.__name

    def get_password(self):
        return self.__password

    def get_id(self):
        return self.__id

实例化一个用户对象user1,并直接进行JSON序列化dumps操作

    user1 = User(1, 'test', 'password')
    print(user1)
    # 直接序列化

    print(json.dumps(user1))

得到报错信息:

TypeError: Object of type ‘User’ is not JSON serializable

User对象无法直接序列化,看下dumps方法的定义:

def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):

注意,default参数定义如下:

default(obj) is a function that should return a serializable version
of obj or raise TypeError. The default simply raises TypeError.

因此,我们给User对象指定一个序列化方法:

def user_to_str(user):
    return {'id': user.get_id(), 'name': user.get_name(), 'password': user.get_password()}

重新执行dumps方法,我们得到如下结果:

{“id”: 1, “name”: “test”, “password”: “password”}

当然,在Python中_dict_是一个特殊的属性,其包含了类的所有属性,因此,我们还可以给User对象指定如下参数

json.dumps(user1, default=lambda obj: obj.dict)

重新运行,我们得到如下结果:

{“_User__id”: 1, “_User__name”: “test”, “_User__password”: “password”}

假设我们重新定义一个Teacher类,如下:

class Teacher(object):
    __slots__ = ('address', 'grade')

    def __repr__(self):
        address = None
        grade = None
        if hasattr(self, 'address'):
            address = self.address
        if hasattr(self, 'grade'):
            grade = self.grade
        return "address is %s, grade is %s" % (address, grade)

注意,与User类略有不同的是,我们通过_slots_内置属性限制了对象Teacher只具备addressgrade属性,我们重新运行方法

json.dumps(teacher, default=lambda obj: obj.dict)

得到报错信息:

AttributeError: ‘Teacher’ object has no attribute ‘dict

使用_slots_限制的类不具备_dict_属性,因此,我们还需要自定实现Teacher类的JSON序列化方法

def teacher_to_str(teacher):
    address = ''
    grade = ''
    if hasattr(teacher, 'address'):
        address = teacher.address
    if hasattr(teacher, 'grade'):
        grade = teacher.grade
    return {'address': address, 'grade': grade}

你可能感兴趣的:(综合,架构,前端,Python,中间件)