Python數(shù)據(jù)類dataclasses的具體使用
一、場(chǎng)景
dataclasses模塊提供了一種方便的方法來(lái)創(chuàng)建和管理數(shù)據(jù)對(duì)象
它可以幫助開(kāi)發(fā)者更容易地創(chuàng)建簡(jiǎn)單的類,同時(shí)提供了一些實(shí)用的功能,例如自動(dòng)實(shí)現(xiàn)__init__()、repr()、eq()等方法。
- 數(shù)據(jù)容器:如果您需要一個(gè)簡(jiǎn)單的類來(lái)存儲(chǔ)一些數(shù)據(jù),例如配置信息、用戶信息、數(shù)據(jù)記錄等,那么使用dataclass是非常合適的。dataclass可以自動(dòng)為您生成適當(dāng)?shù)膶傩院头椒?,以便您可以輕松地訪問(wèn)和修改數(shù)據(jù)。
- 數(shù)據(jù)對(duì)象:如果您的代碼需要處理大量的數(shù)據(jù)對(duì)象,例如在數(shù)據(jù)分析、機(jī)器學(xué)習(xí)、自然語(yǔ)言處理等領(lǐng)域中,那么使用dataclass可以使代碼更加清晰易讀,減少手動(dòng)編寫大量的屬性和方法的重復(fù)性工作。
- 序列化和反序列化:dataclass可以幫助您更輕松地將對(duì)象序列化為JSON、XML等格式,并在需要時(shí)將其反序列化。這使得處理不同系統(tǒng)之間的數(shù)據(jù)交換變得更加容易。
- 數(shù)據(jù)驗(yàn)證和清理:在某些情況下,您可能需要在將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)或發(fā)送到其他系統(tǒng)之前對(duì)其進(jìn)行驗(yàn)證和清理。使用dataclass可以使這個(gè)過(guò)程更加簡(jiǎn)單和可靠。
二、基礎(chǔ)用法
from dataclasses import dataclass, field, asdict, astuple
from typing import List, Any
@dataclass
class Book:
name: str
author: str
# extend: Any = 'hello world' # 擴(kuò)展字段 僅做記錄
publication: str = field(metadata={"description": "出版日期"})
num: int = field(default=1, metadata={"description": "數(shù)量"})
price: float = field(default=0.0, metadata={'currency': 'RMB'})
category: List[str] = field(default_factory=list, repr=False, metadata={"description": "圖書類別"})
def __post_init__(self):
# 方法來(lái)確保書名的每個(gè)單詞的首字母都是大寫的
self.name = self.name.title()
self.title = self.name.upper()
def is_expensive(self):
# 檢查一本書是否價(jià)格高于100
return self.price > 30.0
def total_amount(self):
return self.price * self.num
如何調(diào)用
book = Book(name="Under the sky", author="sanxian", price=37.82, publication="2022-11-07", category=['武俠', '古風(fēng)'])
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 # 修改價(jià)格屬性
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, ['科幻', '懸疑'])
三、中級(jí)用法
裝飾器參數(shù) dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
| 參數(shù)名稱 | 默認(rèn)值 | 是否生成方法 | 說(shuō)明 |
|---|---|---|---|
| init | True | __init__ | 是否生成 __init__ 方法 |
| repr | True | __repr__ | 是否生成 __repr__ 方法 |
| eq | True | __eq__ | 是否生成 __eq__ 方法 |
| order | False | <, <=, >, >= | 是否生成比較方法 |
| unsafe_hash | False | __hash__ | 是否生成 __hash__ 方法 |
| frozen | False | 不可變類 | 是否生成不可變類 |
init 參數(shù)控制是否生成 init 方法。當(dāng)設(shè)置為 True 時(shí),會(huì)自動(dòng)生成 init 方法;當(dāng)設(shè)置為 False 時(shí),不會(huì)生成 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 被設(shè)置為 False,dataclass 不會(huì)自動(dòng)生成 init 方法
init 被設(shè)置為 True(即默認(rèn)),該方法接收兩個(gè)參數(shù) name 和 age,并將存儲(chǔ)在實(shí)例屬性 self.name 和 self.age 中
frozen控制是否創(chuàng)建一個(gè)凍結(jié)的數(shù)據(jù)類,即該類的實(shí)例在創(chuàng)建后就不可變
默認(rèn)情況下,dataclass 創(chuàng)建的類是可變的。
如果你想要?jiǎng)?chuàng)建一個(gè)不可變的類,可以設(shè)置 frozen=True:
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(1, 2)
p.x = 3 # 會(huì)引發(fā) AttributeError: can't set attribute
from dataclasses import dataclass, field, asdict
四、其它用法
field 支持的參數(shù)
| 參數(shù) | 描述 | 默認(rèn)值 |
|---|---|---|
| default | 字段的默認(rèn)值 | |
| default_factory | 返回字段初始值的函數(shù) | |
| init | 是否在._init_()方法中使用字段 | True |
| repr | 是否在._repr_()方法中使用字段 | True |
| compare | 是否在比較對(duì)象時(shí), 包括該字段 | True |
| hash | 計(jì)算hash時(shí), 是否包括字段 | True |
| metadata | 包含字段信息的映射 |
compare 默認(rèn)指定比較,則各個(gè)屬性依次次進(jìn)行比較
注釋:下面僅用年齡進(jìn)行排序或者排序
@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 對(duì)象列表
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() 函數(shù)可以更精細(xì)地控制字段的初始化:
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')
五、使用場(chǎng)景舉例
數(shù)據(jù)記錄:dataclass 非常適合用來(lái)創(chuàng)建數(shù)據(jù)記錄類,尤其是在你需要存儲(chǔ)和處理結(jié)構(gòu)化數(shù)據(jù)時(shí)
@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 也可以用來(lái)創(chuàng)建配置類,使得配置更加直觀和易于管理。
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"])
領(lǐng)域驅(qū)動(dòng)設(shè)計(jì):在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)中,dataclass 可以用來(lái)表示聚合根、實(shí)體和值對(duì)象。
@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)
數(shù)據(jù)驗(yàn)證:結(jié)合第三方庫(kù)如 Pydantic,dataclass 可以用于數(shù)據(jù)驗(yàn)證。
from pydantic import BaseModel
@dataclass
class UserInput(BaseModel):
name: str
age: int
city: str
input_data = UserInput(name="Bob", age=25, city="Los Angeles")
到此這篇關(guān)于Python數(shù)據(jù)類dataclasses的具體使用的文章就介紹到這了,更多相關(guān)python dataclasses內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python中pandas dataframe刪除一行或一列:drop函數(shù)詳解
- python pandas dataframe 按列或者按行合并的方法
- Python Pandas批量讀取csv文件到dataframe的方法
- python中關(guān)于時(shí)間和日期函數(shù)的常用計(jì)算總結(jié)(time和datatime)
- 使用Python向DataFrame中指定位置添加一列或多列的方法
- python中pandas.DataFrame的簡(jiǎn)單操作方法(創(chuàng)建、索引、增添與刪除)
- 在?Python?中創(chuàng)建DataFrame的方法
- python DataFrame獲取行數(shù)、列數(shù)、索引及第幾行第幾列的值方法
相關(guān)文章
Python基于SMTP協(xié)議實(shí)現(xiàn)發(fā)送郵件功能詳解
這篇文章主要介紹了Python基于SMTP協(xié)議實(shí)現(xiàn)發(fā)送郵件功能,結(jié)合實(shí)例形式分析了Python使用SMTP協(xié)議實(shí)現(xiàn)郵件發(fā)送的相關(guān)操作技巧,并總結(jié)分析了Python發(fā)送純文本郵件、郵件附件、圖片郵件等相關(guān)操作技巧,需要的朋友可以參考下2018-08-08
python 在某.py文件中調(diào)用其他.py內(nèi)的函數(shù)的方法
這篇文章主要介紹了python 在某.py文件中調(diào)用其他.py內(nèi)的函數(shù)的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06
python實(shí)現(xiàn)旋轉(zhuǎn)和水平翻轉(zhuǎn)的方法
今天小編就為大家分享一篇python實(shí)現(xiàn)旋轉(zhuǎn)和水平翻轉(zhuǎn)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
Django-migrate報(bào)錯(cuò)問(wèn)題解決方案
這篇文章主要介紹了Django-migrate報(bào)錯(cuò)問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Python tkinter之Bind(綁定事件)的使用示例
這篇文章主要介紹了Python tkinter之Bind(綁定事件)的使用詳解,幫助大家更好的理解和學(xué)習(xí)python的gui開(kāi)發(fā),感興趣的朋友可以了解下2021-02-02

