python--__del__析構(gòu)函數(shù)(二十六)
Python--__del__析構(gòu)函數(shù)(二十六)
Python類似java是有垃圾回收機(jī)制的語言,所以我們不需要像c++一樣通過析構(gòu)函數(shù)來手動釋放內(nèi)存,
但是python也同樣提供了__del__釋放方法。當(dāng)一個對象的引用計數(shù)為0時,會被自動調(diào)用,那么先來說說
引用計數(shù)吧。
1.引用計數(shù)
import sys
class MyClass(object):
def __init__(self):
print('i am __init__ function')
def __del__(self):
print('i am __del__ function')
if __name__ == '__main__':
m1 = MyClass()
m2 = m1
print(sys.getrefcount(m1))
結(jié)果如下圖:
結(jié)果很讓人吃驚吧,只有兩個實(shí)例,為什么引用計數(shù)是3 ?
都知道python是一門腳本語言,解釋型語言,但是不知道大家有沒有注意python其實(shí)也是有編譯過程的。
.pyc文件就是個很好的證明。可以去/usr/lib/python看看
所以說的細(xì)致一點(diǎn)python是一門先編譯后解釋的語言,編譯指的是編譯成為字節(jié)碼,然后然逐行解釋字節(jié)碼。
平時解釋器幫我們做好了而已,你可能會說上面的代碼怎么看不見.pyc文件呢,你把函數(shù)單獨(dú)成一個.py文件
然后import導(dǎo)入后編譯就可以看見了。其實(shí).pyc文件只是編譯后的?PyCodeObject存儲在硬盤上的表現(xiàn)而已。
編譯產(chǎn)生的真正的結(jié)果是PyCodeObject
過程.py ->編譯 -> PyCodeObject ->解釋(虛擬機(jī)執(zhí)行)
現(xiàn)在說引用計數(shù),繞了個彎,其實(shí)也不算,因為引用計數(shù)的值不對就是因為python的編譯過程。
詳情可參考http://blog.csdn.net/balabalamerobert/article/details/1649490
2.__del__
前面說了python的引用計數(shù)為0時會自動回收對象,所以一般是不推薦我們使用python中的__del__刪除方法的
我在自己使用__del__過程中就遇到了一個問題,還是看代碼:
定義了兩個類,一個基類MyClass有名字和電話等信息,派生類DerClass添加了地址,每個類都有一個attribute屬性
glb和der_glb。
class MyClass(object):
glb = 100 #global variable
def __init__(self, nm, ph):
self.name = nm
self.phone = ph
class DerClass(MyClass):
der_glb = 200 #global variable
def __init__(self, nm, ph, addr):
super.__init__(nm, ph) #python3
self.address = addr
def __del__(self):
#del self.__class__.der_glb
del self.der_glb
print 'del der_glb'
if __name__ == '__main__':
m1 = MyClass('wwh', '123')
m2 = DerClass('wwh', '456', 'xian')
主要看下del函數(shù),我在del函數(shù)中自己調(diào)用了del self.der_glb來刪除這個所有類共用的變量
(python中類內(nèi)定義的變量所有實(shí)例共用)
結(jié)果報錯了
但是我改為del self.__class__.der_glb卻正確了
這是什么原因呢
前面說了python中類內(nèi)定義的變量所有實(shí)例共用,那么每個實(shí)例在結(jié)束后也就是自己的引用計數(shù)為0時都會被調(diào)用del
也就是說每個實(shí)例都del了一遍只有一份的der_glb變量,當(dāng)然是不對的
那么為什么加上__class__就正確了呢
python的內(nèi)存模型應(yīng)該是我們定義了一個類后,這個類的模板module也會在內(nèi)存中存儲一份(id(Der_class)可證明),畢竟它還有所有實(shí)例需要用的變量等等。
所以__class__含義應(yīng)該是獲取到內(nèi)存中這個module的地址,然后取得module的der_glb,刪除它。
刪除它后我們當(dāng)然不能使用它了。
類似python的delattr(obj, attr)刪除類的屬性一樣
在我按照上面所說的進(jìn)行修改后,del self.__class__.der_glb,運(yùn)行成功,并且再次定義類的實(shí)例時訪問der_glb屬性報錯,報錯結(jié)果如下:
可見在del der_glb后,再次使用der_glb顯示has no attibute 'der_glb',證明前面我所說的是正確的,該屬性已經(jīng)被刪除
說明一下python中的der_glb類似c++中的static變量,所有實(shí)例被共用,但是在python中被稱為該類的屬性attribute。
轉(zhuǎn)載自:https://blog.csdn.net/wwh578867817/article/details/45398187
Python
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。