當(dāng)Python解釋器終止時,它會嘗試按照以下順序銷毀對象:
- 執(zhí)行已注冊的
atexit
函數(shù)。 - 逐個銷毀模塊。在銷毀模塊時,解釋器會將模塊的全局變量設(shè)置為None。然而,如果存在其他對象仍然持有這些全局變量的引用,那么這些全局變量將不會被完全銷毀,因為它們的引用計數(shù)不為0。
- 對于其他仍然存在的對象,解釋器會嘗試銷毀它們。由于這些對象可能仍然持有全局變量的引用,因此在銷毀這些對象時,它們所依賴的全局變量仍然存在。
然而在某些情況下,當(dāng)解釋器銷毀模塊時,可能會出現(xiàn)一些問題。例如,如果一個對象在其__del__
方法中引用了一個模塊,那么在解釋器銷毀該模塊時,可能會出現(xiàn)NameError異常。這是因為解釋器在銷毀模塊時,會將模塊的全局變量設(shè)置為None,而不是完全銷毀它們。
個人認(rèn)為這個機(jī)制是不合理的。任何工程啟動服務(wù)的時候,要自底向上逐層啟動;停止服務(wù)的時候,應(yīng)當(dāng)自頂向下釋放資源
為什么Python解釋器要首先銷毀所有的模塊和全局變量,然后再銷毀對象?這樣的話,上層對象中引用的一些底層全局依賴先被銷毀,上層對象后被銷毀,很容易引起奇奇怪怪的異常。。
為了避免這種問題,python只能通過一些強(qiáng)制手段或者兜底catch去保障解釋器的“正常”結(jié)束:
- 使用
atexit
模塊來注冊一些在程序終止時執(zhí)行的清理函數(shù) - 在程序終止之前手動執(zhí)行一些清理操作
- 在
__del__
方法中捕獲可能出現(xiàn)的異常