在pypy清理

2024-04-26 05:36:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在寻找用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清理任何东西?在


Tags: 对象方法selfid网页objectinitdef
3条回答

在您的示例中,__del__未被调用,但这只是因为您编写的测试程序立即结束。PyPy保证在对象不再可访问的一段时间后调用__del__,但前提是程序继续执行。因此,如果您在一个无限循环中ft = FooType(1),它将在一段时间后打印died。在

正如其他答案所解释的,CPython并不能真正保证什么,但是在简单的情况下(例如没有引用循环),它将立即可靠地调用__del__。不过,关键是你不应该完全依赖这个。在

在其他Python实现(包括CPython)中也应该采用同样的方法:在代码中显式地管理生存期,而不是依赖自动内存管理和__del__。在

即使在CPython中,也有不止一种情况下__del__根本不被调用,还有很多情况下它的调用比您预期的要晚得多(例如,任何对象在引用循环中被捕获,这很容易发生)。这意味着它基本上是无用的,除了调试生存期问题之外(但是有内存分析器可以用来解决这个问题!)如果某些代码忽略了显式清理,作为最后的手段。在

通过明确的清理,你可以回避所有这些问题。有一个方法来完成清理,并让客户端代码在正确的时间调用它。上下文管理器可以使它更容易在异常情况下正确处理,并且更具可读性。它通常还允许比__del__更快地清理,甚至if引用计数“立即”调用__del__。例如,这:

def parse_file(path):
    f = open(path)
    return parse(f.read()) # file stays open during parsing

比这个w.r.t.资源使用情况更糟:

^{pr2}$

我还认为这样的设计更简洁,因为它不会混淆资源包装器对象的生命周期和被包装资源的生命周期。有时,让对象比资源活得长是有意义的,甚至可以让它拥有新资源的所有权。在

当您需要一个“清理”来确保在特定时间运行时,请使用context manager。在

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

相关问题 更多 >