- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > 編程語(yǔ)言 >
- Python中有哪些數據類(lèi)
本篇文章給大家分享的是有關(guān)Python中有哪些數據類(lèi),小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習,希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著(zhù)小編一起來(lái)看看吧。
創(chuàng )建第一個(gè)數據類(lèi)
創(chuàng )建一個(gè)數據類(lèi),該數據類(lèi)表示三維坐標系中的一個(gè)點(diǎn)。
@dataclass裝飾器用于創(chuàng )建數據類(lèi)。x,y和z是數據類(lèi)中的字段。注意要使用類(lèi)型注釋來(lái)指定字段的數據類(lèi)型,但是類(lèi)型注釋不是靜態(tài)類(lèi)型聲明,這意味著(zhù)仍然可以為x,y或z字段傳遞除int之外的任何數據類(lèi)型。
from dataclasses import dataclass @dataclass classCoordinate: x: int y: int z: int
默認情況下,數據類(lèi)附帶有init、repr和 eq方法,因此我們不必自己實(shí)現。但是如果init、repr和eq沒(méi)有在Coordinate類(lèi)中實(shí)現,有了數據類(lèi),我們仍然可以使用這些方法,這樣非常節省時(shí)間。
from dataclasses import dataclass @dataclass classCoordinate: x: int y: int z: int a =Coordinate(4, 5, 3) print(a) # output: Coordinate(x=4, y=5, z=3)
字段的默認值
編碼者可以為字段分配默認值。如下所示,數據類(lèi)中的pi字段被分配了默認值:
from dataclasses import dataclass @dataclass classCircleArea: r: int pi: float =3.14 @property defarea(self): return self.pi * (self.r **2) a =CircleArea(2) print(repr(a)) # output: CircleArea(r=2, pi=3.14) print(a.area) # output: 12.56
自定義字段和數據類(lèi)
設置dataclass裝飾器或field函數的參數可以自定義字段和數據類(lèi)。自定義過(guò)程將用例子進(jìn)行說(shuō)明,本文結尾也會(huì )給出字段和數據類(lèi)的所有參數。
數據類(lèi)可變還是不可變?
默認情況下,數據類(lèi)是可變的,這意味著(zhù)可以為字段分配值。但我們可以通過(guò)將frozen參數設置為T(mén)rue來(lái)使其不可變
可變示例:
from dataclasses import dataclass @dataclass classCircleArea: r: int pi: float =3.14 @property defarea(self): return self.pi * (self.r **2) a =CircleArea(2) a.r =5 print(repr(a)) # output: CircleArea(r=5, pi=3.14) print(a.area) # output: 78.5
不可變示例:
設置frozen為 True,將無(wú)法再為字段分配值。在下面的示例中可以看到異常輸出。
from dataclasses import dataclass @dataclass(frozen=True) classCircleArea: r: int pi: float =3.14 @property defarea(self): return self.pi * (self.r **2) a =CircleArea(2) a.r =5 # Exceptionoccurred: dataclasses.FrozenInstanceError: # cannot assign tofield 'r'
比較數據類(lèi)
假設要創(chuàng )建一個(gè)表示Vector的數據類(lèi)并進(jìn)行比較,你會(huì )怎么做?當然需要使用諸如lt或gt之類(lèi)的方法啦。
默認情況下,數據類(lèi)的order參數為 False。將其設置為T(mén)rue,會(huì )自動(dòng)為數據類(lèi)生成 lt、le、gt和ge方法。因此,可以按順序比較對象,就像它們是其字段的元組一樣。
研究下面的示例:將order設置為T(mén)rue就可以比較v2和v1。這里存在一個(gè)邏輯比較的問(wèn)題。當v2> v1時(shí),它將比較這兩個(gè)向量,例如(8,15)>(7,20)。因此,v2> v1的輸出將為T(mén)rue。
回想一下,元組比較是逐個(gè)按照順序進(jìn)行的。首先將8和7進(jìn)行比較,結果為T(mén)rue,那么比較結果就為T(mén)rue。如果它們相等,則比較15> 20,結果為False:
from dataclasses import dataclass,field @dataclass(order=True) classVector: x: int y: int v1 =Vector(8, 15) v2 =Vector(7, 20) print(v2 > v1)
顯然這種比較沒(méi)有任何意義。筆者最初想通過(guò)向量的大小來(lái)比較它們。但問(wèn)題是,不可能在創(chuàng )建每個(gè)實(shí)例時(shí),都要自己計算Vector的大小。
在這種情況下,field函數和post_init方法更有用。field函數能自定義magnitude字段。而post_init方法則會(huì )確定初始化后該矢量的大小。
還可以使用數據類(lèi)中的field函數來(lái)自定義magnitude字段。通過(guò)將init設置為False,基本可以不需要init方法中的magnitude參數。因為初始化后才使用post_init方法來(lái)確定其值:
from dataclasses import dataclass, field @dataclass(order=True) classVector: magnitude: float =field(init=False) x: int y: int def__post_init__(self): self.magnitude = (self.x **2+ self.y **2) **0.5 v1 =Vector(9, 12) print(v1) # output: Vector(magnitude=15.0, x=9,y=12) v2 =Vector(8, 15) print(v2) # output: Vector(magnitude=17.0, x=8,y=15) print(v2 > v1) # output: True
將數據類(lèi)轉換為字典或元組
從元組或字典中獲取數據類(lèi)的屬性,只需要從數據類(lèi)中導入asdict和astuple函數:
from dataclasses import dataclass,asdict, astuple @dataclass classVector: x: int y: int z: int v =Vector(4, 5, 7) print(asdict(v)) # output: {'x': 4, 'y': 5, 'z': 7} print(astuple(v)) # output: (4, 5, 7)
繼承
可以像Python中的普通類(lèi)一樣對數據類(lèi)進(jìn)行子類(lèi)化:
from dataclasses import dataclass @dataclass classEmployee: name: str lang: str @dataclass classDeveloper(Employee): salary: int Halil=Developer('Halil', 'Python', 5000) print(Halil) # Output: Developer(name='Halil',lang='Python', salary=5000)
使用繼承時(shí)經(jīng)常會(huì )忽視一點(diǎn):默認情況下,當將lang字段設置為Python時(shí),必須為lang字段之后的字段提供默認值:
from dataclasses import dataclass @dataclass classEmployee: name: str lang: str ='Python' @dataclass classDeveloper(Employee): salary: int Halil=Developer('Halil', 'Python', 5000) # Output:TypeError: non-default argument 'salary' follows default argument
原因在于init方法?;叵胍幌?,具有默認值的參數應該位于沒(méi)有默認值的參數之后:
def__init__(name: str,lang: str ='Python', salary: int): ...
通過(guò)對sanlary字段設置默認值來(lái)對其進(jìn)行修復:
from dataclasses import dataclass @dataclass classEmployee: name: str lang: str ='Python' @dataclass classDeveloper(Employee): salary: int =0 Halil=Developer('Halil', 'Python', 5000) print(Halil) # output: Developer(name='Halil',lang='Python', salary=5000)
slots的好處
默認情況下,屬性存儲在字典中。使用slots可以更快地訪(fǎng)問(wèn)屬性并且內存占用更少。
from dataclasses import dataclass @dataclass classEmployee: name: str lang: str Halil=Employee('Halil', 'Python') print(Halil.__dict__) # name': 'Halil', 'lang': 'Python'}
slots內存占用更小,訪(fǎng)問(wèn)屬性更快。
from dataclasses import dataclass @dataclass classEmployee: __slots__ = ('name', 'lang') name: str lang: str Halil=Employee('Halil', 'Python')
數據類(lèi)參數
剛剛我們更改了數據類(lèi)裝飾器中的某些參數,以自定義數據類(lèi)。以下是參數列表:
nit:如果為T(mén)rue,則在數據類(lèi)中生成init方法。(默認為T(mén)rue)
repr:如果為T(mén)rue,則在數據類(lèi)中生成repr方法。(默認為T(mén)rue)
eq:如果為T(mén)rue,則在數據類(lèi)中生成eq方法。(默認為T(mén)rue)
order:如果為T(mén)rue,則在數據類(lèi)中生成lt,le,gt和ge方法。(默認為False)
unsafe_hash:如果為T(mén)rue,則在數據類(lèi)中生成hash方法。(默認為False)
frozen:如果為T(mén)rue,則不能給字段分配值。(默認為False。)
注意,如果order為T(mén)rue,eq必須也為T(mén)rue,否則將引發(fā)ValueError異常。
字段參數
init:如果為T(mén)rue,則此字段包含在生成的init方法中。(默認為T(mén)rue)
repr:如果為T(mén)rue,則此字段包含在生成的repr方法中。(默認為T(mén)rue)
compare:如果為T(mén)rue,則此字段包含在生成的比較和相等方法中。(默認為T(mén)rue)
hash:如果為T(mén)rue,則此字段包含在生成的hash方法中。(默認為None)
default:這是此字段的默認值(如果提供)。
default_factory:當該字段需要默認值時(shí)將調用該參數,此時(shí)該參數必須為零階可調用參數對象。
metadata:可以是映射,也可以為空,為空則將其視為空字典。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站