发生break语句时生成器销毁

时间:2012-01-26 22:03:34

标签: python generator

我想知道Obj。 del()方法的时间 将被称为。

def my_integers():
    Obj = ExitObj()
    i = 0
    while(1):
        yield i
        i += 1
def test_fun():
    for i in my_integers():
        if i > 3:
            break 
anything_function()
test_fun()

我做了一个测试,Obj似乎在break语句之后被删除:在anything_function()之前循环。

当循环留给生成器内定义的对象的__ del__方法时,我可以依赖于此并提供一些我想要完成的任务吗?

3 个答案:

答案 0 :(得分:9)

  

我想知道何时调用Obj.__del__()方法。

你做不到。它可能永远不会。 Python中的终结器(或者在任何具有自动垃圾收集器方案的环境中)都不能保证完全运行,并且只能用于最后的清理。如果您想要可预测的生命周期管理,请使用with statementcontext managers

class Foo(object):
    def __enter__(self):
        print 'Entered with block'
    def __exit__(self, *exc_info):
        print 'Exited with block'
        return False

with Foo():
    pass

答案 1 :(得分:2)

通常,您不能依赖析构函数调用顺序。当垃圾收集器回收对象时,将调用析构函数。这可以在无限期的未来发生,或者如果您的程序因异常而死亡,则根本不会发生。

如果您想要对象的确定生命周期,请考虑creating it inside a @contextmanager-decorated function并使用with语句。

答案 2 :(得分:0)

以下是Python语言参考说明回合object.__del__(self)

  

x.__del__() - 只在x的引用计数达到零时调用。可能阻止对象的引用计数变为零的一些常见情况包括:对象之间的循环引用;对捕获异常的函数的堆栈帧上的对象的引用...

因此,您不应该依赖__del__进行清理。上下文管理器(作为Cat Plus Plus mentions above)是正确的选择。