Python数据类dataclasses的具体使用

 更新时间:2025年11月25日 11:01:48   作者:风华浪浪  
dataclasses模块简化了创建具有默认值和自动初始化功能的Python类,它能生成__init__、__repr__等方法,并支持序列化、数据验证和清理,下面就来具体介绍一下如何使用,感兴趣的可以了解一下

一、场景

dataclasses模块提供了一种方便的方法来创建和管理数据对象
它可以帮助开发者更容易地创建简单的类,同时提供了一些实用的功能,例如自动实现__init__()、repr()、eq()等方法。

  • 数据容器:如果您需要一个简单的类来存储一些数据,例如配置信息、用户信息、数据记录等,那么使用dataclass是非常合适的。dataclass可以自动为您生成适当的属性和方法,以便您可以轻松地访问和修改数据。
  • 数据对象:如果您的代码需要处理大量的数据对象,例如在数据分析、机器学习、自然语言处理等领域中,那么使用dataclass可以使代码更加清晰易读,减少手动编写大量的属性和方法的重复性工作。
  • 序列化和反序列化:dataclass可以帮助您更轻松地将对象序列化为JSON、XML等格式,并在需要时将其反序列化。这使得处理不同系统之间的数据交换变得更加容易。
  • 数据验证和清理:在某些情况下,您可能需要在将数据存储到数据库或发送到其他系统之前对其进行验证和清理。使用dataclass可以使这个过程更加简单和可靠。

二、基础用法

from dataclasses import dataclass, field, asdict, astuple
from typing import List, Any

@dataclass
class Book:
    name: str
    author: str
    # extend: Any = 'hello world'   # 扩展字段 仅做记录
    publication: str = field(metadata={"description": "出版日期"})
    num: int = field(default=1, metadata={"description": "数量"})
    price: float = field(default=0.0, metadata={'currency': 'RMB'})
    category: List[str] = field(default_factory=list, repr=False, metadata={"description": "图书类别"})

    def __post_init__(self):
        # 方法来确保书名的每个单词的首字母都是大写的
        self.name = self.name.title()
        self.title = self.name.upper()

    def is_expensive(self):
        # 检查一本书是否价格高于100
        return self.price > 30.0

    def total_amount(self):

        return self.price * self.num

如何调用

book = Book(name="Under the sky", author="sanxian", price=37.82, publication="2022-11-07", category=['武侠', '古风'])
book = Book(**{"name": "the three body problem", "author": "刘慈欣", "price": 37.82, "publication": "2022-12-23", "category": ['科幻', '悬疑']})
print(book.name, book.author)
print(book.title)

print(book.is_expensive())
print(book.total_amount())

book.price = 27.5  # 修改价格属性
print(book.is_expensive())  # 输出:True

print(asdict(book))
print(astuple(book))
The Three Body Problem 刘慈欣 2022-12-23 37.82
THE THREE BODY PROBLEM
True
37.82
False
{'name': 'The Three Body Problem', 'author': '刘慈欣', 'publication': '2022-12-23', 'num': 1, 'price': 27.5, 'category': ['科幻', '悬疑']}
('The Three Body Problem', '刘慈欣', '2022-12-23', 1, 27.5, ['科幻', '悬疑'])

三、中级用法

装饰器参数 dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)

参数名称默认值是否生成方法说明
initTrue__init__是否生成 __init__ 方法
reprTrue__repr__是否生成 __repr__ 方法
eqTrue__eq__是否生成 __eq__ 方法
orderFalse<, <=, >, >=是否生成比较方法
unsafe_hashFalse__hash__是否生成 __hash__ 方法
frozenFalse不可变类是否生成不可变类

init 参数控制是否生成 init 方法。当设置为 True 时,会自动生成 init 方法;当设置为 False 时,不会生成 init 方法。

@dataclass(init=False)
class Person:
    name: str
    age: int

    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

p = Person("zhangsan", 30)
print(p.name) # 输出: Alice
print(p.age)  # 输出: 30

init 被设置为 False,dataclass 不会自动生成 init 方法
init 被设置为 True(即默认),该方法接收两个参数 name 和 age,并将存储在实例属性 self.name 和 self.age 中

frozen控制是否创建一个冻结的数据类,即该类的实例在创建后就不可变
默认情况下,dataclass 创建的类是可变的。
如果你想要创建一个不可变的类,可以设置 frozen=True:

from dataclasses import dataclass

@dataclass(frozen=True)
class Point:
    x: int
    y: int

p = Point(1, 2)
p.x = 3  # 会引发 AttributeError: can't set attribute
from dataclasses import dataclass, field, asdict

四、其它用法

field 支持的参数

参数描述默认值
default字段的默认值
default_factory返回字段初始值的函数
init是否在._init_()方法中使用字段True
repr是否在._repr_()方法中使用字段True
compare是否在比较对象时, 包括该字段True
hash计算hash时, 是否包括字段True
metadata包含字段信息的映射

compare 默认指定比较,则各个属性依次次进行比较
注释:下面仅用年龄进行排序或者排序

@dataclass(order=True)
class Person:
    name: str = field(compare=False)
    age: int = field(compare=True)
    height: float = field(compare=False)

p1 = Person(name="A-zhangsan", age=25, height=156)
p2 = Person(name="B-lisi", age=18, height=173)
p3 = Person(name="C-wanger", age=20, height=168)

print(p2 > p1)  # 输出 True
print(sorted([p1,p2, p3]))  # 输出按薪资排序的 Person 对象列表
False
[
	Person(name='B-lisi', age=18, height=173), 
	Person(name='C-wanger', age=20, height=168), 
	Person(name='A-zhangsan', age=25, height=156)
]

控制字段初始化:使用 field() 函数可以更精细地控制字段的初始化:

from dataclasses import field

@dataclass
classPersonWithField:
    name:str= field(init=False)
    age:int
    city:str

def__post_init__(self):
        self.name =f"{self.age} year(s) old in {self.city}"

person_with_field =PersonWithField(age=30, city="New York")
print(person_with_field.name)  # 输出: 30 year(s) old in New York

排除某些字段:如果你想在 repr() 方法中排除某些字段,可以使用 repr=False:

@dataclass(repr=False)
class PersonPartialRepr:
    name: str
    age: int = field(repr=False)
    city: str

partial_repr_person = PersonPartialRepr(name="Alice", age=30, city="New York")
print(partial_repr_person)  # 输出: Person(name='Alice', city='New York')

五、使用场景举例

数据记录:dataclass 非常适合用来创建数据记录类,尤其是在你需要存储和处理结构化数据时

@dataclass
class SalesRecord:
    product: str
    quantity: int
    price: float
    timestamp: str

record = SalesRecord(product="Widget", quantity=100, price=19.99, timestamp="2023-04-01T12:00:00")

配置文件:dataclass 也可以用来创建配置类,使得配置更加直观和易于管理。

from typing importList

@dataclass
classConfig:
    database:str
    port:int
    debug:bool=False
    tables:List[str]= field(default_factory=list)

config =Config(database="mydb", port=5432, debug=True, tables=["users","products"])

领域驱动设计:在领域驱动设计中,dataclass 可以用来表示聚合根、实体和值对象。

@dataclass(frozen=True)
classUser:
	id:int
	username:str
	email:str

@dataclass
classUserBuilder:
	id:int=None
	username:str=None
	email:str=None

def build(self):
	if self.id is None or self.username is None or self.email is None:
		raiseValueError("All fields are required")
	returnUser(id=self.id, username=self.username, email=self.email)

数据验证:结合第三方库如 Pydantic,dataclass 可以用于数据验证。

from pydantic import BaseModel

@dataclass
class UserInput(BaseModel):
    name: str
    age: int
    city: str

input_data = UserInput(name="Bob", age=25, city="Los Angeles")

到此这篇关于Python数据类dataclasses的具体使用的文章就介绍到这了,更多相关python dataclasses内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详谈pandas中agg函数和apply函数的区别

    详谈pandas中agg函数和apply函数的区别

    下面小编就为大家分享一篇详谈pandas中agg函数和apply函数的区别,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-04-04
  • Python线程之同步机制实际应用场景举例说明

    Python线程之同步机制实际应用场景举例说明

    这篇文章主要给大家分享的是Python线程之同步机制实际应用场景举例说明,银行转账小栗子供大家参考学习,希望对你有一定的帮助
    2022-02-02
  • Python 捕获代码中所有异常的方法

    Python 捕获代码中所有异常的方法

    这篇文章主要介绍了Python 捕获代码中所有异常的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • Python通过requests模块实现抓取王者荣耀全套皮肤

    Python通过requests模块实现抓取王者荣耀全套皮肤

    只学书上的理论是远远不如实践带来的提升快,只有在实例中才能获得能力的提升,本篇文章手把手带你用Python实现抓取王者荣耀全套皮肤,大家可以在过程中查缺补漏,提升水平
    2021-10-10
  • django跳转页面传参的实现

    django跳转页面传参的实现

    这篇文章主要介绍了django跳转页面传参的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Python中操作MySQL和SQL Server数据库的实战指南

    Python中操作MySQL和SQL Server数据库的实战指南

    本文详细介绍了如何在Pvthon中使用pymysql和pymssql库进行MySQL和SQLServer数据库的基本操作,包括连接、查询、插入、更新、异常处理、参数化查询、ORM应用、事务处理以及连接池的使用,为读者提供了一套全面的数据库操作指南,需要的朋友可以参考下
    2025-11-11
  • opencv 形态学变换(开运算,闭运算,梯度运算)

    opencv 形态学变换(开运算,闭运算,梯度运算)

    这篇文章主要介绍了opencv 形态学变换(开运算,闭运算,梯度运算),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Python+OpenCV实现分水岭分割算法的示例代码

    Python+OpenCV实现分水岭分割算法的示例代码

    分水岭算法是用于分割的经典算法,在提取图像中粘连或重叠的对象时特别有用。本文将用Python+OpenCV实现这一算法,需要的可以参考一下
    2022-08-08
  • CentOS6.5设置Django开发环境

    CentOS6.5设置Django开发环境

    这篇文章主要为大家详细介绍了CentOS6.5设置Django开发环境,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • Python编程中NotImplementedError的使用方法

    Python编程中NotImplementedError的使用方法

    下面小编就为大家分享一篇Python编程中NotImplementedError的使用方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-04-04

最新评论