dataclass介绍
dataclass 是dataclasses模块提供的一个装饰器,当一个普通的类被dataclass装饰时,这个普通的类将被赋予一些神奇的魔法,这对于我们处理数据是十分有帮助的。dataclass所装饰的类仍然属于面向对象范畴,它并没有发明新的轮子,而是对旧轮子进行了改造升级,让开发人员在处理数据时更便捷。
通过与普通类进行比较,我们能非常清晰的看到dataclass所带来的优势:
- dataclass 优势
- 可读性强
- 操作灵活
- 轻量
- 应用场景
- 创建对象
- 完美融合平台开发 ORM 框架
通过__init__方法进行实现
场景:如果创建一只猫,信息包括猫的名字、体重、颜色。同时打印这个对象的时候,希望能打印出一个字符串(包含猫的各种信息)应该如何编写代码
class Cat:
name: str
color: str
weight: int
def __init__(self,name,color,weight):
self.name = name
self.color = color
self.weight = weight
def __str__(self):
return f"喵星人姓名:{self.name},颜色:{self.color},体重:{self.weight}"
def __repr__(self):
return f"===>>喵星人姓名:{self.name},颜色:{self.color},体重:{self.weight}"
cat = Cat("Tom","橘黄",2)
print(cat)
- 问题:
- 数据修改不方便
- 代码冗余
- 解决方案:
- 使用自定义类实现数据类
使用dataclass来实现
from dataclasses import dataclass
@dataclass
class Cat:
name: str
color: str
weight: int
if __name__ == "__main__":
cat = Cat("Tom", "橘黄", 2)
print(cat)
dataclass field 的使用
当想要知道小猫每次生下多少个孩子,而且想默认children值时,这个我们需要用到field来实现默认参数
# 错误写法,执行报错
@dataclass
class Cat:
name: str
color: str
weight: int
children: list=[1,2,3]
- 默认值是list&dict情况下,用list=field(default_factory=list&dict)来实现,不能list=field(default_factory=[1,2,3]&{"name":"Tom"}或者[] {}),当有值传过来时,用传过来的值进行填充,如果没有传过值,默认值children=[]&{}
# 正确写法,可变类型必须使用field
from dataclasses import dataclass,field
@dataclass
class Cat:
name: str
color: str
weight: str = field(default=5)
children: list = field(default_factory=list)
children1: dict = field(default_factory=dict)
if __name__ == '__main__':
cat = Cat("菠萝", "橘猫", 9, [1,2,3])
- 没有传参数的情况下
from dataclasses import dataclass,field
@dataclass
class Cat:
name: str
color: str
weight: int=2
children: list=field(default_factory=list)
if __name__ == "__main__":
cat = Cat("Tom", "橘黄", 9)
print(cat)
- 如果想默认不是空的list和dict,需要用到匿名函数lambda来实现
from dataclasses import dataclass,field
@dataclass
class Cat:
name: str
color: str
weight: str = field(default=5)
children: list = field(default_factory=list)
children1: dict = field(default_factory=dict)
children2: list = field(default_factory=lambda:[1,2,3])
children3: dict = field(default_factory=lambda: {"name":"喵"})
if __name__ == "__main__":
cat = Cat("Tom", "橘黄", 9)
print(cat)
- 对于非list和dict的默认值实现,用field(default=5)
from dataclasses import dataclass,field
@dataclass
class Cat:
name: str
color: str
weight: int= field(default=5)
if __name__ == "__main__":
cat = Cat("Tom", "橘黄")
print(cat)
- field init 参数
- 如果为
True
(默认值),该字段作为参数包含在生成的init()
方法中。 - 如果为
False
,该字段不会包含init()
方法参数中。
- 如果为
from dataclasses import dataclass,field
@dataclass
class Cat:
name: str
color: str
weight: str = field(default=5)
children: list = field(default_factory=list,init=False)
if __name__ == "__main__":
cat = Cat("Tom", "橘黄")
print(cat)
-
field repr 参数
- 如果为
True
(默认值),该字段包含在生成的repr()
方法返回的字符串中。 - 如果为
False
,该字段不会包含在生成的repr()
方法返回的字符串中。
- 如果为
from dataclasses import dataclass,field
@dataclass
class Cat:
name: str
color: str
weight: str = field(default=5,init=False)
children: list = field(default_factory=list,repr=False)
if __name__ == "__main__":
cat = Cat("Tom", "橘黄")
print(cat)
当repr=False时,返回结果中是没有children的
当repr=True时,返回结果中是有children的
asdict()
转化实例对象为字典格式
from dataclasses import dataclass,field
@dataclass
class Cat:
name: str
color: str
weight: str = field(default=5,init=False)
children: list = field(default_factory=list,repr=True)
if __name__ == "__main__":
cat = Cat("Tom", "橘黄")
print(cat)
#通过asdict()转换成字典格式
data = dataclasses.asdict(cat)
print(data)