注:本文是對http://www.datadependence.com/2016/07/pythonic-code-video-series-slots/的翻譯竿拆。說是翻譯鳖藕,但不會逐字逐句翻譯。宗旨是回答標(biāo)題的問題孝情,所以也會增加自己的理解鱼蝉。
很多人都看過Oyster.com的這篇相當(dāng)當(dāng)?shù)奈恼拢?/p>
SAVING 9 GB OF RAM WITH PYTHON’S_SLOTS_
為了能夠理解_slots_,最好的方式是先了解域是如何關(guān)聯(lián)python類的◇锏矗考慮下面這個類:
classMeasurement:def__init__(self,x,y,value):self.x = x? ? ? ? self.y = y? ? ? ? self.val = value
假如我們創(chuàng)建少量幾個這個類的實體魁亦,通過初始化方法設(shè)置值,并給一個實體動態(tài)增加屬性及值羔挡,如下:
m1 =Measurement(1,2,"Happy")m2 =Measurement(7,10,"Crazy")
那在內(nèi)存中的存儲大概類似如下:
從上圖可以看到洁奈,每個實體都有指向一個包括屬性名及屬性值的_dict_。我們可以打印出來:
print(m1.__dict__) #{'x':1,'y':2,'val':'happy'}print(m2.__dict__) #{'x':7,'y':10,'other':True,'val':'Crazy'}
如果我們不是像m2.other = True那樣在類創(chuàng)建好后定制屬性绞灼。并且利术,我們要創(chuàng)建非常非常多的實例(比如,百萬級)低矮,那這種方式就是非常低效的——我們需要在內(nèi)存中存儲對應(yīng)實體數(shù)量包含重復(fù)鍵的字典印叁。
使用_slots_
只要簡單的修改下Measurement類的屬性的存儲就能消除重復(fù),得到一個1比1的字典分配军掂。
classMeasurement:__slots__ = ['x','y','val']def__init__(self,x,y,value):self.x = x? ? ? ? self.y = y? ? ? ? self.val = value
1
2
3
4
5
6
(譯者注:原文是在python3上實現(xiàn)的喉钢。因為python3只有新式類,無需任何指定良姆。但是如果是在python2(譯者熟悉的2.6/2.7)上肠虽。上面的寫法就是錯誤的,具體看下代碼玛追,運行后就知道了)
classMeasurement(object):__slots__ = ['x','y','val']def__init__(self,x,y,value):self.x = x? ? ? ? self.y = y? ? ? ? self.val = valueclassMeasurement_old:__slots__ = ['x','y','val']def__init__(self,x,y,value):self.x = x? ? ? ? self.y = y? ? ? ? self.val = valuem1 = Measurement(1,2,"new")m2 = Measurement_old(2,3,"old")printdir(Measurement)printdir(Measurement_old)printtype(Measurement.x)##print m1.__dict__ #AttributeErrorprintm2.__dict__#{'y': 3, 'x': 2, 'val': 'old'}
這樣税课,內(nèi)存中的存儲就大概類似這樣的了:
現(xiàn)在從圖可以看出,屬性名和Measurement類關(guān)聯(lián)痊剖,而不再是和它的實體關(guān)聯(lián)韩玩。好處是顯而易見的。