python 的__del__刪除器方法__python

來源:互聯網
上載者:User

遇到了python關於del的小問題,又引發了一些問題,就簡單的記錄下,如果有不同意見,歡迎一起討論~



python類似java是有記憶體回收機制的語言,所以我們不需要像c++一樣通過解構函式來手動釋放記憶體,

但是python也同樣提供了__del__釋放方法。當一個對象的引用計數為0時,會被自動調用,那麼先來說說

引用計數吧。

1.引用計數

#!/usr/bin/env python
#coding:UTF-8import sysclass 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))

結果如下圖:


結果很讓人吃驚吧,只有兩個執行個體,為什麼引用計數是3 ? 

都知道python是一門指令碼語言,解釋型語言,但是不知道大家有沒有注意python其實也是有編譯過程的。

.pyc檔案就是個很好的證明。可以去/usr/lib/python看看

所以說的細緻一點python是一門先編譯後解釋的語言,編譯指的是編譯成為位元組碼,然後然逐行解釋位元組碼。

平時解譯器幫我們做好了而已,你可能會說上面的代碼怎麼看不見.pyc檔案呢,你把函數單獨成一個.py檔案

然後import匯入後編譯就可以看見了。其實.pyc檔案只是編譯後的 PyCodeObject儲存在硬碟上的表現而已。

編譯產生的真正的結果是PyCodeObject

過程.py ->編譯 -> PyCodeObject ->解釋(虛擬機器執行)

現在說引用計數,繞了個彎,其實也不算,因為引用計數的值不對就是因為python的編譯過程。


詳情可參考http://blog.csdn.net/balabalamerobert/article/details/1649490


2.__del__


前面說了python的引用計數為0時會自動回收對象,所以一般是不推薦我們使用python中的__del__刪除方法的

我在自己使用__del__過程中就遇到了一個問題,還是看代碼:

定義了兩個類,一個基類MyClass有名字和電話等資訊,衍生類別DerClass添加了地址,每個類都有一個attribute屬性

glb和der_glb。

#!/usr/bin/env python#coding:UTF-8class MyClass(object):    glb = 100                #global variable    def __init__(self, nm, ph):        self.name = nm        self.phone = phclass 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函數,我在del函數中自己調用了del self.der_glb來刪除這個所有類共用的變數

(python中類內定義的變數所有執行個體共用)

結果報錯了


但是我改為del self.__class__.der_glb卻正確了

這是什麼原因呢

前面說了python中類內定義的變數所有執行個體共用,那麼每個執行個體在結束後也就是自己的引用計數為0時都會被調用del

也就是說每個執行個體都del了一遍只有一份的der_glb變數,當然是不對的

那麼為什麼加上__class__就正確了呢

python的記憶體模型應該是我們定義了一個類後,這個類的模板module也會在記憶體中儲存一份(id(Der_class)可證明),畢竟它還有所有執行個體需要用的變數等等。

所以__class__含義應該是擷取到記憶體中這個module的地址,然後取得module的der_glb,刪除它。

刪除它後我們當然不能使用它了。

類似python的delattr(obj, attr)刪除類的屬性一樣

在我按照上面所說的進行修改後,del self.__class__.der_glb,運行成功,並且再次定義類的執行個體時訪問der_glb屬性報錯,報錯結果如下:


可見在del der_glb後,再次使用der_glb顯示has no attibute 'der_glb',證明前面我所說的是正確的,該屬性已經被刪除

說明一下python中的der_glb類似c++中的static變數,所有執行個體被共用,但是在python中被稱為該類的屬性attribute。


雖然python很好用,但是也需要搞清楚一些原理 ^_^






相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.