Python?中的對象析構(gòu)函數(shù)__del__?詳情

前言:
Python 中的類的構(gòu)造函數(shù) ??__init__?? , 每當(dāng)實例產(chǎn)生就會調(diào)用這個構(gòu)造函數(shù)。
反過來,每當(dāng)實例對象需要被垃圾收集被收回時,就需要用到析構(gòu)函數(shù) ??__del__?? 。
??__del__?? 方法是類的一種特殊方法??梢岳???__del__?? 方法來清理資源,例如關(guān)閉文件。
來看一個例子:
class Life:
? ? def __init__(self, name='None'):
? ? ? ? print('Hello,' + name)
? ? ? ? self.name = name
? ? def live(self):
? ? ? ? print(self.name)
? ??
? ? def __del__(self):
? ? ? ? print("Goodbye," + self.name)
def main():
? ? bob = Life('Bob')
? ? bob.live()
if __name__ == '__main__':
? ? main()運行該代碼,輸出結(jié)果為:
Hello,Bob
Bob
Goodbye,Bob
我們得到上面的輸出是因為當(dāng)代碼即將結(jié)束時,不再需要類 Life,因此它已準(zhǔn)備好被銷毀。 在類 Life 被銷毀之前,會自動調(diào)用 ??__del__?? 方法。
還可以通過調(diào)用 ??del?? 手動調(diào)用 ??__del__?? 方法:
class Life:
? ? def __init__(self, name='None'):
? ? ? ? print('Hello,' + name)
? ? ? ? self.name = name
? ? def live(self):
? ? ? ? print(self.name)
? ??
? ? def __del__(self):
? ? ? ? print("Goodbye," + self.name)
def main():
? ? bob = Life('Bob')
? ? del bob
if __name__ == '__main__':
? ? main()執(zhí)行結(jié)果:
Hello,Bob
Goodbye,Bob
值得注意的是:??del x?? 并不直接調(diào)用 ??x.__del__()?? ,前者將 x 的引用計數(shù)減一,而后者僅在其引用計數(shù)達到零時才被調(diào)用。
在 Python 中,任何未使用的對象(如內(nèi)置類型或類的實例)在不再使用時會自動從內(nèi)存中刪除(移除)。 這種釋放和回收未使用內(nèi)存空間的過程稱為垃圾回收。
在Python中何時使用__del__?
重要的是要注意,當(dāng)對象處于銷毀的過程中,調(diào)用 ??__del__?? 方法(未損壞后),因此仍然可以在__del__方法中訪問屬性。
由于??__del__?? 可以訪問對象的數(shù)據(jù)成員,因此應(yīng)該確保對象的填充刪除,以便沒有內(nèi)存泄露。
class App:
? ? def __init__(self):
? ? ? ? print("Open App")
? ? def __del__(self):
? ? ? ? print("Closed App")
class Phone:
? ? app = None
? ? def __init__(self):
? ? ? ? print("Switching on the Phone")
? ? ? ? self.__class__.app = App()
? ? def __del__(self):
? ? ? ? del self.__class__.app
? ? ? ? print("Switching off the Phone")
phone = Phone()
del phone執(zhí)行結(jié)果:
Switching on the Phone
Open App
Closed App
Switching off the Phone
在這個例子中,如果我們沒有在??__del__?? 方法中銷毀手機的屬性 app,它就會留在內(nèi)存中,導(dǎo)致內(nèi)存泄漏。
析構(gòu)函數(shù)使用緊要
Python 中的析構(gòu)函數(shù)并不像 C++ 中那樣被頻繁使用,因為它存在一些眾所周知的警告和極少數(shù)鮮為人知的暗坑。
盡量減少使用 ??__del__?? 函數(shù):
- 第一,因為 Python 在回收實例時,會自動回收該實例擁有的所有內(nèi)存空間,所以析構(gòu)函數(shù)并不需要考慮空間管理。所以也就失去了手動寫 ??
__del__??的意義。 - 第二,無法預(yù)測一個實例什么時候會被回收。有時候你想觸發(fā)析構(gòu)函數(shù)時,系統(tǒng)表中對對象的引用會阻止析構(gòu)函數(shù)的執(zhí)行。Python 也無法保證解釋器退出時,一個仍然存在的對象會調(diào)用其析構(gòu)函數(shù)。
- 第三,??__del__?? 可能會引發(fā)的異常會直接向
sys.stderr(標(biāo)準(zhǔn)錯誤流) 打印一條警告消息,而不是觸發(fā)一個異常事件。因為它通過垃圾收集器運行在不可預(yù)料的上下文中。 - 第四,當(dāng)我們期待垃圾回收時,對象間的循環(huán)引用可能會阻止其發(fā)生。
總結(jié):
- 當(dāng)對象被銷毀時,Python 會自動調(diào)用對象上的 ??__del__?? 方法(??類似于在對象創(chuàng)建期間調(diào)用的 ??__init__?? 構(gòu)造函數(shù))。
- ??__del__?? 方法類似于 C++ 和 Java 中的析構(gòu)函數(shù)。用于銷毀對象的狀態(tài)。
- Python 中,盡量減少析構(gòu)函數(shù)的使用。
到此這篇關(guān)于Python 中的對象析構(gòu)函數(shù)__del__ 詳情的文章就介紹到這了,更多相關(guān)Python 對象析構(gòu)函數(shù)del內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python?中的對象析構(gòu)函數(shù)__del__?詳情
這篇文章主要介紹了Python?中的對象析構(gòu)函數(shù)del詳情,Python?中的類的構(gòu)造函數(shù)???__init__???,?每當(dāng)實例產(chǎn)生就會調(diào)用這個構(gòu)造函下面更多相關(guān)內(nèi)容,需要的小伙伴可以參考一下2022-03-03
python腳本實現(xiàn)數(shù)據(jù)導(dǎo)出excel格式的簡單方法(推薦)
下面小編就為大家?guī)硪黄猵ython腳本實現(xiàn)數(shù)據(jù)導(dǎo)出Excel格式的簡單方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12
python中使用mysql數(shù)據(jù)庫詳細介紹
這篇文章主要介紹了python中使用mysql數(shù)據(jù)庫詳細介紹,本文起講解了安裝mysql、安裝MySQL-python、mysql 的基本操作、python 操作mysql數(shù)據(jù)庫基礎(chǔ)等內(nèi)容,需要的朋友可以參考下2015-03-03
python實現(xiàn)翻轉(zhuǎn)棋游戲(othello)
這篇文章主要為大家詳細介紹了python實現(xiàn)翻轉(zhuǎn)棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07

