2015-12-17 84 views
2

有沒有辦法讓一個類刪除它自己的一個實例。我知道變量你可以做del x,但你怎麼做類?如果我這樣做:Python中的類實例刪除

class foo(object): 
    x=5 
    def __init__(self): 
     print "hi" 
    def __del__(self): 
     del self 
     print "bye" 

a = foo() 
a.__del__() 
print a.x 

代碼的輸出是

hi 
bye 
5 

未刪除foo的實例。有沒有辦法讓班級做到這一點?

+0

'刪除了'可能?它在這裏做的竅門 – asiviero

+0

http://stackoverflow.com/questions/16686788/python-how-to-kill-a-class-instance-object –

+0

對於記錄,「x」甚至不是「a ',它是'foo'的類屬性;無論是否存在由'a'引用的'foo'實例,它都不會消失。 – ShadowRanger

回答

0

沒有,如果你有一個參考該類的實例,那麼根據定義它有剩餘的引用。您可以使用del關鍵字來刪除一個名稱(釋放該名稱對該對象的引用),但如果對該實例的引用在其他地方存在,則該實例將保留。

如果你要做的是確定性清理行爲,不要使用__del__(這是不明確的或一致的方式確定性,並且在Python 3.4之前,如果週期中的任何成員可能導致引用循環泄漏是定義了一個__del__終結器的類的一個實例)。讓類實現the context manager protocol,並使用with語句的實例來獲得確定性清理;該實例將一直存在,直到最後一個引用消失,但只要__exit__執行必要的資源釋放,實例的空殼就幾乎沒有任何成本。

由於上下文管理的一個例子,我們會讓xfoo實例屬性,而不是一個類屬性,我們會說,我們需要確保該實例的引用x在已知的時間(注意消失,因爲del只是刪除我們的參考,如果別人得救關閉a.x,對象實際上不會被釋放,直到其他的參考文獻中也被釋放):

class foo(object): 
    def __init__(self, x): 
     self.x = x 
     print "hi" 
    def __enter__(self): 
     return self 
    def __exit__(self, exc_type, exc_val, exc_tb): 
     print "bye" 
     del self.x 

with foo(123456789) as a: 
    print a.x # This works, because a.x still exists 
# bye is printed at this point 
print a.x # This fails, because we deleted the x attribute in __exit__ and the with is done 
# a still exists until it goes out of scope, but it's logically "dead" and empty 
0

通過定義__del__我相信你重寫了del的默認行爲。正如您可以閱讀here,__del__一旦對象的引用計數達到0,就會調用它。除非您知道自己在做什麼,否則不建議使用__del__

編輯:這是不正確的,請檢查shadowranger的答案。雖然鏈接仍然與蟒蛇2

+0

這是錯誤的。 del關鍵字刪除一個名稱(或者在某些情況下,從容器中引用),從而釋放對與該名稱關聯的對象的引用。但是,如果別處有其他引用,'del'只會(在CPython中)減少引用計數。當最後一個引用消失時,不管是否涉及del,都會調用__del__。這兩者只有切線相關;對於有或沒有'__del__'的類的實例,'del'本身沒有什麼不同,只有Python垃圾處理過程發生變化。 – ShadowRanger

+0

那麼你去,我顯然沒有做我的CPython垃圾收集功課。看起來我今天也學到了一些東西,不過我相信你有點跳過槍。我從來沒有說''__del__'是由'del'專門調用的,引用計數等於零與沒有引用相同,但我絕對會100%承認我的答案是誤導性的,第一句是錯誤的。 – OnGle

-1

del a應該做的伎倆:

代碼:

class foo(object): 
    x=5 
    def __init__(self): 
     print "hi" 
    def __del__(self): 
     del self 
     print "bye" 

a = foo() 
del a 
print a.x 

輸出:

$ python test.py 
hi 
here 
bye 
Traceback (most recent call last): 
    File "test.py", line 12, in <module> 
    print a.x 
NameError: name 'a' is not defined