怎樣使用python中的__slots__方法?這個(gè)問題可能是我們?nèi)粘W(xué)習(xí)或工作經(jīng)常見到的。希望通過這個(gè)問題能讓你收獲頗深。下面是小編給大家?guī)淼膮⒖純?nèi)容,讓我們一起來看看吧!
憑借整站使用成都h5網(wǎng)站建設(shè)的創(chuàng)新體驗(yàn)、定制設(shè)計(jì)、設(shè)計(jì)團(tuán)隊(duì)積累與透明式的服務(wù)過程,符合行業(yè)特點(diǎn),專屬顧問根據(jù)企業(yè)產(chǎn)品,消費(fèi)群體屬性,準(zhǔn)確定位;設(shè)計(jì)師以目標(biāo)客戶為中心,以突出品牌官網(wǎng)特性為宗旨,定制專屬網(wǎng)站建設(shè)設(shè)計(jì)方案。
__slots__的簡(jiǎn)介
__slots__是可以在定義Python類時(shí)添加的屬性。
您可以使用對(duì)象實(shí)例可以擁有的可能屬性來定義插槽。
使用__slots__的方法如下:
class WithSlots: __slots__ = ('x', 'y') def __init__(self, x, y): self.x, self.y = x, y
使用__slots__的更高層次的最大原因是:
1.由于數(shù)據(jù)結(jié)構(gòu)優(yōu)化而更快地獲取和設(shè)置屬性;
2.減少了類實(shí)例的內(nèi)存使用量。 不想使用它的某些原因是,
3.如果類具有在運(yùn)行時(shí)更改的屬性(動(dòng)態(tài)屬性),或者存在復(fù)雜的對(duì)象繼承樹。
我們做個(gè)測(cè)試數(shù)據(jù):
首先,我們先進(jìn)行一些測(cè)試,以查看__slots__何時(shí)更快,從批量實(shí)例化開始。 使用Python的“ timeit”模塊和此代碼段,我們得到以下結(jié)果:
class WithoutSlots: def __init__(self, x, y, z): self.x = x self.y = y self.z = z class WithSlots: __slots__ = ('x', 'y', 'z') def __init__(self, x, y, z): self.x = x self.y = y self.z = z def instance_fn(cls): def instance(): x = cls(1, 2, 3) return instance Without Slots: 0.3909880230203271 With Slots: 0.31494391383603215 (averaged over 100000 iterations)
在這種情況下,使用slots的實(shí)例化速度稍快。 這很有意義,因?yàn)槲覀兙芙^為給定對(duì)象的新實(shí)例創(chuàng)建__dict__。 字典通常比元組或列表有更多內(nèi)存開銷。 讓我們嘗試一個(gè)具有更多與實(shí)例相關(guān)聯(lián)的屬性的類!
Without Slots: 1.5249411426484585 With Slots: 1.52750033326447 (averaged over 100000 iterations)
通常,使用__slots__并不能真正縮短實(shí)例化時(shí)間。 盡管不必創(chuàng)建__dict__,但是還有其他開銷需要我們稍后再使用的slots來完成,這導(dǎo)致了類似于從實(shí)際類中復(fù)制字典的運(yùn)行時(shí)間。
當(dāng)我們開始快速連續(xù)獲取和設(shè)置值時(shí),真正的加速就起作用了:
def get_set_fn(cls): x = cls(list(range(26))) def get_set(): x.y = x.z + 1 x.a = x.b - 1 x.d = x.q + 3 x.i = x.j - 1 x.z = x.y / 2 return get_set Without Slots: 11.59717286285013 With Slots: 9.243316248897463 (averaged over 100000 iterations)
速度提高了20%以上! 如果測(cè)試范圍更廣(并且不總是訪問相同的屬性,且屬性的長(zhǎng)度比單個(gè)字符長(zhǎng)),則可以實(shí)現(xiàn)更大的加速。
內(nèi)存使用情況
首先,讓我們測(cè)試元組和字典在內(nèi)存中的增長(zhǎng)方式之間的區(qū)別。 當(dāng)使用__slots__知道給定實(shí)例可以存在哪些屬性時(shí),它可以為與實(shí)例相關(guān)聯(lián)的描述符分配(而不必為每個(gè)新對(duì)象添加__dict__)。
在Python中,很難描述對(duì)象實(shí)例使用的確切內(nèi)存量:sys.getsizeof僅適用于基元和內(nèi)置函數(shù)。 相反,我們將在名為“ Pympler”的庫(kù)中使用名為asizeof的函數(shù)。
import sys #沒有這一句會(huì)報(bào)錯(cuò) sys.getsizeof(('a', 'b', 'c', 'd')) >>> asizeof(('a', 'b', 'c', 'd')) 304 >>> asizeof({'a': 'b', 'c': 'd'}) 512 >>> asizeof(tuple(string.ascii_lowercase)) 1712 >>> dictionary {'e': 'f', 'k': 'l', 'c': 'd', 'g': 'h', 'o': 'p', 'i': 'j', 's': 't', 'm': 'n', 'q': 'r', 'a': 'b', 'y': 'z', 'w': 'x', 'u': 'v'} >>> asizeof(dictionary) 2320
我們?cè)谶@里省略了__slots__示例的實(shí)現(xiàn)細(xì)節(jié):我們沒有將一個(gè)元組用于描述符,一個(gè)元組用于值,而是將它們?nèi)糠旁谝粋€(gè)列表中。 但是,與元組和dict之間的差異相比,我們發(fā)現(xiàn)大小的差異并不大:
>>> asizeof(('a', 'b')) + asizeof(('c', 'd')) 352 為了更好的測(cè)量,當(dāng)我們?cè)谏弦粋€(gè)示例類的slots上實(shí)際運(yùn)行asizeof時(shí),會(huì)發(fā)生以下情況: >>> w1 = WithoutSlots(1, 2, 3) >>> asizeof(w1) 416 >>> w2 = WithSlots(4, 5, 6) >>> asizeof(w2) 160
感謝各位的閱讀!看完上述內(nèi)容,你們對(duì)怎樣使用python中的__slots__方法大概了解了嗎?希望文章內(nèi)容對(duì)大家有所幫助。如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。