Last active
January 2, 2016 11:59
-
-
Save kjelly/8300078 to your computer and use it in GitHub Desktop.
探討 python 的 __del__ 行為
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import weakref | |
class Case1(object): | |
def __del__(self): | |
print 'del case1' | |
class Case2(object): | |
_instance = None | |
def __new__(cls, *args, **kwargs): | |
if not cls._instance: | |
cls._instance = super(cls, cls).__new__( | |
cls, *args, **kwargs) | |
return cls._instance | |
def __del__(self): | |
print 'del case2' | |
class Case3(object): | |
_weakref_instance = None | |
def __new__(cls, *args, **kwargs): | |
if (cls._weakref_instance is None) or (cls._weakref_instance() is None): | |
cls._weakref_instance = weakref.ref(super(cls, cls).__new__( | |
cls, *args, **kwargs)) | |
return cls._weakref_instance() | |
def __del__(self): | |
print 'del case3' | |
a = Case1() | |
b = Case2() | |
c = Case3() | |
raise Exception |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
這是一個簡單的程式,來描述 del 的特別行為
建立 a, b, c 三個物件,分別對應到 Case1, Case2, Case3
當程式有未處理的例外,而導致程式停止時,
Case1 物件的 del 會被呼叫。
但是在 Case2 物件,程式停止前所作的 gc
並不會清除 Case2,因為有類別變數指向他。
所以如果類別變數是用 weakref 指向他的話,像 Case3
則 Case3 的 del 會被呼叫。
至於 Case2 的行為,這篇文章 http://docs.python.org/2/reference/datamodel.html#object.__del__
說 "It is not guaranteed that del() methods are called for objects that still exist when the interpreter exits."。
我比較好奇他為什麼要這樣設計XD