[英]Cleaning up in pypy
我一直在尋找清理python對象的方法。 我目前正在使用pypy。
我找到了一個網頁和一個示例。
首先是一個基本示例:
class FooType(object):
def __init__(self, id):
self.id = id
print self.id, 'born'
def __del__(self):
print self.id, 'died'
ft = FooType(1)
此應打印:
1出生1死亡
但是它只打印1個出生的
所以我的問題是:如何清除PyPy中的任何內容?
當您需要在特定時間確定運行“清理”時,請使用上下文管理器 。
class FooType(object):
def __init__(self, id):
self.id = id
print 'born'
def __enter__(self):
print 'entered'
return self
def __exit__(self, *exc):
print 'exited'
with FooType(1) as ft:
pass # do something with ft
在其他所有Python實現中( 包括CPython)也應以相同的方式進行操作:通過顯式管理代碼的生存期,而不是依靠自動內存管理和__del__
。
即使在CPython的,有一個以上的情況下__del__
完全不叫,並且相當多的情況下,這就是所謂的要晚得多比你想象的(例如,任何時候任何對象獲取的參考周期趕上了,這很能發生容易)。 這意味着它實際上是沒有用的,除了可能調試生命周期問題(但是有內存分析器!),並且如果某些代碼忽略了明確清理,則是不得已而為之。
通過明確地進行清理,您可以避開所有這些問題。 擁有進行清理的方法,並使客戶端代碼在正確的時間調用它。 上下文管理器可以使它更容易在遇到異常時正確處理,並且更具可讀性。 它往往還允許比清理越早__del__
, 即使引用計數“立即”調用__del__
。 例如,這:
def parse_file(path):
f = open(path)
return parse(f.read()) # file stays open during parsing
比此wrt資源使用情況差:
def parse_file(path):
with open(path) as f:
s = f.read()
# file is closed here
return parse(s)
我還認為這樣的設計更干凈,因為它不會混淆資源包裝器對象的生存期和被包裝資源的生存期。 有時,使該對象的資源有效期更長,甚至使其擁有新資源的所有權也很有意義。
在您的示例中,未調用__del__
,但這僅是因為您編寫的測試程序立即完成了。 PyPy保證在無法再訪問該對象之后的某個時間調用__del__
,但__del__
是只要程序繼續執行即可。 因此,如果您在無限循環中執行ft = FooType(1)
,它也會在一段時間后打印died
。
正如其他答案所解釋的那樣,CPython並不能真正保證任何事情,但是在簡單的情況下(例如,沒有參考周期),它將立即可靠地調用__del__
。 重點仍然是,您不應該嚴格依賴於此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.