Skip to content

Dataclass

Python 数据类 dataclass

简介

数据类是 Python3.7 开始引入的一个新功能, 数据类提供了开箱即用的方法来创建自定义数据类, 可以直接实例化、打印和比较数据类实例。

dataclass 基本使用

使用 dataclass 之前需要使用 from dataclasses import dataclass 进行导入,然后以装饰器的形式进行使用。

默认情况下,@dataclass 装饰器会生成 __repr____init____eq__ 三个方法。

from dataclasses import dataclass

@dataclass
class Student:
    name: str
    age: int
    gender: str

if __name__ == '__main__':
    tom1 = Student("tom", 22, "male")
    print(tom1)
    tom2 = Student("Tom", 22, "male")
    print(tom2)
    print(tom1 == tom2)

通过 dataclass 装饰器,可以避免具有大量属性的类中的初始化方法的冗余代码的书写。

数据类嵌套

一个数据类,可以做为另外一个数据类中的字段进行使用。

from dataclasses import dataclass

@dataclass
class Student:
    name: str
    age: int
    gender: str

@dataclass
class Class:
    name: str
    member: list[Student]


if __name__ == '__main__':
    tom = Student("Tom", 22, "male")
    jack = Student("Jack", 22, "male")
    p1 = Class("Pthon1", [tom, jack])
    print(p1)

对象初始化后禁止改变属性值

在某些场景下,数据在使用过程中并不想被修改,但是如果使用模型数据类实例,是不可能实现的,但是在使用 dataclass 时,可以指定 frozen=True 参数来实现该功能。

from dataclasses import dataclass

@dataclass(frozen=True)
class Student:
    name: str
    age: int
    gender: str



if __name__ == '__main__':
    tom = Student("Tom", 22, "male")
    # tom.name = "tom"  # 不允许执行该行代码

field 的使用

类中的属性,可以使用 field 字段进行定制属性的功能。

参数 描述 默认值
default 字段的默认值
default_factory 返回字段初始值的函数
init 是否在.init()方法中使用字段 True
repr 是否在.repr()方法中使用字段 True

field default 参数

  • 字段的默认值
    • default 用来指定不可变类型的默认值
    • default_factory 用来指定可变类型的默认值,对于可变类型需要使用工厂方法来返回一个可变类型的数据做为默认值,不可以直接指定一个可变类型做为默认值
    • 指定默认值的属性,必须在所有属性的最后顺序,后面不能再出现没有默认值的属性
from dataclasses import dataclass

@dataclass
class Cat:
    name: str
    color: str
    weight: str = field(default=5)
    children: list = field(default_factory=list)
    children1: list = field(default_factory=lambda:[1,2,3])
    children2: dict = field(default_factory=lambda: {"name":"喵"})



if __name__ == '__main__':
    tom = Cat("Tom", "red")
    print(tom)

field repr 参数

  • 如果为 True(默认值),该字段包含在生成的 repr() 方法返回的字符串中。
  • 如果为 False,该字段不会包含在生成的 repr() 方法返回的字符串中。
@dataclass
class Cat:
    name: str
    color: str = field(repr=False)
    weight: str


if __name__ == '__main__':
    tom = Cat("tom", "red", 5)
    print(tom)

field init 参数

  • 如果为 True(默认值),该字段作为参数包含在生成的 init() 方法中。
  • 如果为 False,该字段不会包含 init() 方法参数中。
  • 设置为不初始化的属性,在打印实例对象时会报错,解决方法有两种
    • 在指定 initFalse 的同时指定 repr 也为 False
    • 在使用对象信息之前,对未初始化的属性进行赋值

方式一

@dataclass
class Cat:
    name: str
    color: str = field(init=False, repr=False)
    weight: str


if __name__ == '__main__':
    tom = Cat("tom", 5)
    print(tom)

方式二

@dataclass
class Cat:
    name: str
    color: str = field(init=False)
    weight: str


if __name__ == '__main__':
    tom = Cat("tom", 5)
    tom.color = "red"
    print(tom)

常用的方法

  • asdict() 转化实例对象为字典格式
@dataclass
class Cat:
    name: str
    color: str = field(init=False)
    weight: str


if __name__ == '__main__':
    tom = Cat("tom", 5)
    tom.color = "red"
    print(tom)
    tom_d = asdict(tom)
    print(tom_d)