在程序中间调用析构函数

2024-10-05 21:53:41 发布

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

我有一个关于对象销毁和在程序中间调用析构函数的查询

例:

class ABC: 

    # Initializing 
    def __init__(self): 
        print('Constructor Called') 

    # Destructor 
    def __del__(self): 
        print('Destructor called')

obj = ABC() 
del obj 
# I want destructor to be called here.
# and then print below statement
print("obj deleted") 

但在程序结束时调用析构函数

有什么帮助吗,德夫


Tags: 对象函数selfobjinitdefclassabc
2条回答

当对象的引用计数达到0时,或者在循环引用的情况下由垃圾收集器遍历时,调用__del__方法。例如,以下各项:

class Foo:
    def __del__(self):
        print('Foo has been deleted!')

foo = Foo()
del foo

将正确调用__del__方法并打印Foo has been deleted!,因为分配给foo的对象只被引用一次。现在我们来看看下面的例子:

class Foo:
    def __del__(self):
        print('Foo has been deleted!')

foo = Foo()
foo.self = foo
del foo

无法调用__del__方法,因为foo.self将自身作为人质。只有当垃圾收集器遍历它时,才会将其删除。例如:

from gc import collect

class Foo:
    def __del__(self):
        print('Foo has been deleted!')

foo = Foo()
foo.self = foo
del foo

collect()

将调用__del__方法,因为我们告诉收集器遍历挂起的对象。不建议这样做,但您可以通过将阈值设置为1来告诉Python遍历所有队列。例如:

from gc import set_threshold

set_threshold(1, 1, 1)

class Foo:
    def __del__(self):
        print('Foo has been deleted!')

foo = Foo()
foo.self = foo
del foo

因此,每次实例化一个对象时,收集器都会执行其运行。但同样,不建议这样做,因为这样做成本高昂,并且会影响代码的性能

有关详细信息,请参见__del__()here)的文档:

Note del x doesn’t directly call x.__del__() — the former decrements the reference count for x by one, and the latter is only called when x’s reference count reaches zero.

如果您试图“解构”一个Python对象(注意我在引号中是怎么说的),我建议您使用__exit__()with语句(docshere

要使用with语句,请使用以下方法定义一个类:

def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)

下面是一个简单的例子:

class Bar:
    def __init__(self, *args):
        self.stack = list(args)

    def __enter__(self):
        # Example computation here.
        filtered = filter(lambda x: isinstance(x, str), self.stack)
        return list(filtered)

    def __exit__(self, exc_type, exc_value, traceback):
        del self.stack

# Once you leave the 'with' statement, this Bar() object will be deleted for good. 
with Bar("Hello", "World!", 1, 2) as stack:
    print(stack)

尽管坦率地说,在Python中“解构”一个对象几乎是不需要的,而且在大多数情况下,编程时应该避免尝试执行garbage collector的工作。使用del是一回事,但尝试“解构”对象是另一回事

相关问题 更多 >