新聞中心

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比興和網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式興和網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋興和地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。
Python dataclass(數(shù)據(jù)類)簡(jiǎn)介
Python 在版本 3.7 (PEP 557) 中引入了dataclass。dataclass允許你用更少的代碼和更多的開箱即用功能來定義類。
下面定義了一個(gè)具有兩個(gè)實(shí)例屬性 name 和 age 的常規(guī) Person 類:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
這個(gè) Person 類具有初始化 name 和 age 屬性的__init__ 方法。
如果你想要一個(gè) Person 對(duì)象的字符串表示,你需要實(shí)現(xiàn)__str__ 或 __repr__方法。另外,如果要通過屬性比較 Person 類的兩個(gè)實(shí)例,則需要實(shí)現(xiàn)__eq__方法。
但是,如果你使用數(shù)據(jù)類,你將擁有所有這些功能(甚至更多),而無需實(shí)現(xiàn)這些 dunder 方法。
要使 Person 類成為數(shù)據(jù)類,請(qǐng)執(zhí)行以下步驟:
首先,從 dataclasses 模塊導(dǎo)入 dataclass 裝飾器:
from dataclasses import dataclass
其次,用 dataclass 裝飾器裝飾 Person 類并聲明屬性:
@dataclass
class Person:
name: str
age: int
在這個(gè)例子中,Person 類有兩個(gè)屬性 name 類型為 str 和 age 類型為 int, 這樣@dataclass 裝飾器隱式創(chuàng)建__init__方法,如下所示:
def __init__(name: str, age: int)
請(qǐng)注意,類中聲明的屬性的順序?qū)Q定__init__ 方法中參數(shù)的順序。
你可以創(chuàng)建 Person 的對(duì)象:
p1 = Person('John', 25)當(dāng)打印出 Person 的對(duì)象時(shí),你會(huì)得到一個(gè)可讀的格式:
print(p1)
輸出:
Person(name='John', age=25)
此外,如果你比較兩個(gè)具有相同屬性值的 Person 對(duì)象,它將返回 True。例如:
p1 = Person('John', 25)
p2 = Person('John', 25)
print(p1 == p2)輸出
True
下面討論數(shù)據(jù)類提供的其他功能。
默認(rèn)值
使用常規(guī)類時(shí),你可以定義屬性的默認(rèn)值。例如,以下 Person 類的 iq 參數(shù)的默認(rèn)值為 100。
class Person:
def __init__(self, name, age, iq=100):
self.name = name
self.age = age
self.iq = iq
要為數(shù)據(jù)類中的屬性定義默認(rèn)值,請(qǐng)將其分配給屬性,如下所示:
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
iq: int = 100
print(Person('John Doe', 25))
與參數(shù)規(guī)則一樣,具有默認(rèn)值的屬性必須出現(xiàn)在沒有默認(rèn)值的屬性之后。因此,以下代碼將不起作用:
from dataclasses import dataclass
@dataclass
class Person:
iq: int = 100
name: str
age: int
轉(zhuǎn)換為元組或字典
dataclasses 模塊具有 astuple() 和 asdict() 函數(shù),它們將數(shù)據(jù)類的實(shí)例轉(zhuǎn)換為元組和字典。例如:
from dataclasses import dataclass, astuple, asdict
@dataclass
class Person:
name: str
age: int
iq: int = 100
p = Person('John Doe', 25)
print(astuple(p))
print(asdict(p))
輸出:
('John Doe', 25, 100)
{'name': 'John Doe', 'age': 25, 'iq': 100}
創(chuàng)建不可變對(duì)象
要從數(shù)據(jù)類創(chuàng)建只讀對(duì)象,可以將數(shù)據(jù)類裝飾器的凍結(jié)參數(shù)設(shè)置為 True。例如:
from dataclasses import dataclass, astuple, asdict
@dataclass(frozen=True)
class Person:
name: str
age: int
iq: int = 100
如果你在創(chuàng)建對(duì)象后嘗試更改其屬性,則會(huì)收到錯(cuò)誤消息。例如:
p = Person('Jane Doe', 25)
p.iq = 120錯(cuò)誤信息:
dataclasses.FrozenInstanceError: cannot assign to field 'iq'
自定義屬性行為
如果不想在 __init__ 方法中初始化屬性,可以使用 dataclasses 模塊中的 field() 函數(shù)。
以下示例定義了使用 __init__方法初始化的 can_vote 屬性:
from dataclasses import dataclass, field
class Person:
name: str
age: int
iq: int = 100
can_vote: bool = field(init=False)
field() 函數(shù)有多個(gè)有趣的參數(shù),例如 repr、hash、compare 和 metadata。
如果要初始化一個(gè)依賴于另一個(gè)屬性值的屬性,可以使用__post_init__ 方法。顧名思義,Python 在 __init__方法之后調(diào)用 __post_init__ 方法。
下面使用__post_init__ 方法根據(jù) age 屬性初始化 can_vote 屬性:
from dataclasses import dataclass, field
@dataclass
class Person:
name: str
age: int
iq: int = 100
can_vote: bool = field(init=False)
def __post_init__(self):
print('called __post_init__ method')
self.can_vote = 18 <= self.age <= 70
p = Person('Jane Doe', 25)
print(p)
輸出:
called the __post_init__ method
Person(name='Jane Doe', age=25, iq=100, can_vote=True)
對(duì)對(duì)象進(jìn)行排序
默認(rèn)情況下,數(shù)據(jù)類實(shí)現(xiàn) __eq__方法。
要允許不同類型的比較,如__lt__、__lte__、__gt__、__gte__,你可以將 @dataclass 裝飾器的 order 參數(shù)設(shè)置為 True:
@dataclass(order=True)
通過這樣做,數(shù)據(jù)類將按每個(gè)字段對(duì)對(duì)象進(jìn)行排序,直到找到不相等的值。
在實(shí)踐中,你經(jīng)常希望通過特定屬性而不是所有屬性來比較對(duì)象。為此,你需要定義一個(gè)名為 sort_index 的字段并將其值設(shè)置為要排序的屬性。
例如,假設(shè)你有一個(gè) Person 對(duì)象列表,并希望按年齡對(duì)它們進(jìn)行排序:
members = [
Person('John', 25),
Person('Bob', 35),
Person('Alice', 30)
]
因?yàn)?,需要?
- 首先,將 order=True 參數(shù)傳遞給 @dataclass 裝飾器。
- 其次,定義 sort_index 屬性并將其 init 參數(shù)設(shè)置為 False。
- 第三,在 __post_init__方法中將 sort_index 設(shè)置為 age 屬性,以按年齡對(duì) Person 的對(duì)象進(jìn)行排序。
from dataclasses import dataclass, field
@dataclass(order=True)
class Person:
sort_index: int = field(init=False, repr=False)
name: str
age: int
iq: int = 100
can_vote: bool = field(init=False)
def __post_init__(self):
self.can_vote = 18 <= self.age <= 70
# sort by age
self.sort_index = self.age
members = [
Person(name='John', age=25),
Person(name='Bob', age=35),
Person(name='Alice', age=30)
]
sorted_members = sorted(members)
for member in sorted_members:
print(f'{member.name}(age={member.age})')
輸出:
John(age=25)
Alice(age=30)
Bob(age=35)
總結(jié)
- 使用 dataclasses 模塊中的 @dataclass 裝飾器使類成為數(shù)據(jù)類。數(shù)據(jù)類對(duì)象默認(rèn)實(shí)現(xiàn)__eq__和__str__。
- 使用 astuple() 和 asdict() 函數(shù)將數(shù)據(jù)類的對(duì)象轉(zhuǎn)換為元組和字典。
- 使用 freeze=True 定義一個(gè)對(duì)象不可變的類。
- 使用 __post_init__ 方法初始化依賴于其他屬性的屬性。
- 使用 sort_index 指定數(shù)據(jù)類對(duì)象的排序?qū)傩浴?/li>
本文題目:一文帶你了解什么是DataClass?
文章網(wǎng)址:http://www.dlmjj.cn/article/dpccose.html


咨詢
建站咨詢
