web开发中有这么一个场景,我们从数据库中查询某一数据的时候,往往需要对数据进行一些转化之后才能传给前端。
当然我们可以根据查询出来的实例对象,构建一个dict返回,这样会导致我们的代码非常的臃肿。但是这也确实是一种最直接的方式。
除此之外我们来看另外一种方式。
调用类的__dict__函数将类的一些属性转化字典进行序列化
import json
class UserTest:
# 类变量
name = "hou"
age = 18
# 实例变量
def __init__(self):
self.nickname = "user1"
user = UserTest()
print(json.dumps(user))
# 直接序列化一个对象是会报错的
# TypeError: Object of type UserTest is not JSON serializable
dct = user.__dict__
print(json.dumps(dct))
{"nickname": "user1"}
此时你会看到类变量通过__dict__函数是不会被转化字典从而被序列化的。
如果我们想要将类变量也转化为字典从而被序列化那要怎么办呢?
此时你需要重写这两个函数def keys(self)
和def __getitem__(self, item)
class User:
name = "hou"
age = 18
def __init__(self):
self.nickname = "user1"
def keys(self):
# keys函数可以通过dict(self)返回对象构建字典的key集合
# 重写keys函数,类的属性也可以通过dict的形式进行访问
# 返回值必须是一个可迭代的对象
return ("name", "age", "nickname")
def __getitem__(self, item):
# 根据item获取对象属性的值
return getattr(self, item)
user = User()
print(user.name) # 对象.属性访问
print(user["name"]) # 字典形式访问
print(user["age"])
print(user["nickname"])
# dict在传入对象实例的时候会尝试构建字典
# 通过对象的keys获取对象的键值,__getitem__获取对象属性的值
dct = dict(user)
print(dct)
# {'name': 'hou', 'age': 18, 'nickname': 'user1'}
此时还有一个问题,如果我们只想通过dict(对象)返回特定的属性如何操作呢?
此时只要在keys
函数中指定返回的集合即可。
class User:
name = "hou"
age = 18
def __init__(self):
self.nickname = "user1"
def keys(self):
return ("name", "nickname")
def __getitem__(self, item):
return getattr(self, item)
user = User()
dct = dict(user)
print(dct)
# {'name': 'hou', 'nickname': 'user1'}
如果一个类的属性比较多,我们只想根据传参的集合来构架字典从而序列化如何做呢?
我们只需要在类实例化的时候指定keys
需要返回的字段即可。
class User:
name = "hou"
age = 18
def __init__(self):
self.nickname1 = "user1"
self.nickname2 = "user2"
self.nickname3 = "user3"
self.nickname4 = "user4"
self.nickname5 = "user5"
# self.fields = ["name", "age", "nickname1", "nickname2", "nickname3", "nickname4", "nickname5"]
self.fields = []
def keys(self):
return self.fields
def __getitem__(self, item):
return getattr(self, item)
def to_dict(self, *keys):
for key in keys:
self.fields.append(key)
user = User()
user.to_dict("nickname1", "nickname3")
dct = dict(user)
print(dct)
# {'nickname1': 'user1', 'nickname3': 'user3'}