当前位置: 代码网 > it编程>前端脚本>Python > Python数据类dataclasses的具体使用

Python数据类dataclasses的具体使用

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

一、场景

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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com