Python 数据类 dataclass

dataclass 介绍

  • dataclass 优势
    • 可读性强
    • 操作灵活
    • 轻量
  • 应用场景
    • 创建对象
    • 完美融合平台开发 ORM 框架

案例

  • 场景:如果创建一只猫,信息包括猫的名字、体重、颜色。同时打印这个对象的时候,希望能打印出一个字符串(包含猫的各种信息)应该如何编写代码
    • 问题:
      • 数据修改不方便
      • 代码冗余
    • 解决方案:
      • 使用自定义类实现数据类
class Cat:
    name: str
    color: str
    weight: int

    def __init__(self,name,weight,color):
        self.name = name
        self.weight = weight
        self.color = color

    def __str__(self):
        return f"喵星人姓名:{self.name}, 年龄:{self.weight},颜色:{self.color}"

    def __repr__(self):
        return f"===>>>>> 喵星人姓名:{self.name}, 年龄:{self.weight},颜色:{self.color}"

数据类更优雅的实现方案

  • 使用 dataclass 创建数据类
  • 实例化的时候自动生成构造函数
from dataclasses import dataclass
@dataclass
# 1、加类装饰器@dataclass
# 2、为类变量添加类型提示
class Cat:
    name: str
    color: str
    weight: int

if __name__ == '__main__':
    cat = Cat("菠萝", "橘猫", 9)

field 的使用

# 错误写法,执行报错
@dataclass
class Cat:
    name: str
    color: str
    weight: int
    children: list=[1,2,3]
# 正确写法,可变类型必须使用field
from dataclasses import dataclass, field

@dataclass
class Cat:
    name: str
    color: str
    weight: int = 2
    # 可变参数list、dict,需要通过default_factory来指定类型或者默认值
    children: list = field(default_factory=list)

if __name__ == '__main__':
    cat = Cat("菠萝", "橘猫", 9, [1,2,3])

field 常用参数

参数名 参数功能
default 字段的默认值
default_factory 定义可变量参数的默认值,default 和 default_factory 不能同时存在
init 如果为 true(默认值),该字段作为参数包含在生成的 init() 方法中。
repr 如果为 true(默认值),该字段包含在生成的 repr() 方法返回的字符串中。

field default 参数

  • 字段的默认值
@dataclasses.dataclass
class Cat:
    name: str
    color: str
    weight: str = dataclasses.field(default=5)
    children: list = dataclasses.field(default_factory=list)
    children1: list = dataclasses.field(default_factory=lambda:[1,2,3])
    children2: dict = dataclasses.field(default_factory=lambda: {"name":"喵"})

field init 参数

  • 如果为 True(默认值),该字段作为参数包含在生成的 init() 方法中。
  • 如果为 False,该字段不会包含 init() 方法参数中。
    体现在:实例化的时候,是否需要传递这个参数
@dataclasses.dataclass
class Cat:
    name: str
    color: str
    weight: str = dataclasses.field(default=5)
    # init=False,在实例化对象的时候,不需要设置这个值,需要给一个默认值
    children: list = dataclasses.field(default_factory=list,init=False)

field repr 参数

  • 如果为 True(默认值),该字段包含在生成的 repr() 方法返回的字符串中。
  • 如果为 False,该字段不会包含在生成的 repr() 方法返回的字符串中。
@dataclasses.dataclass
class Cat:
    name: str
    color: str
    weight: str = dataclasses.field(default=5)
    # epr=False,在打印这个对象的时候,就不会包括这个字段
    children: list = dataclasses.field(default_factory=list,repr=False)

常用的方法

  • asdict() 转化实例对象为字典格式
class Cat:
    name: str
    color: str
    weight: int = dataclasses.field(default=5)
    # 无参的函数
    children: list = dataclasses.field(default_factory=lambda:[1,2,3])
    children1: dict = dataclasses.field(default_factory=lambda: {"name":"喵"})

cat = Cat("aa","red",10,[1,3],{"name":"喵喵"})
dataclasses.asdict(cat)

总结

  • 可读性强
  • 操作灵活
  • 轻量