Skip to main content
 首页 » 编程设计

python之覆盖析构函数而不调用他们的 parent

2024年10月01日4tintown

我正在编写一个继承自某个库的类。

在上述类(class)中,我重写了析构函数,这样我就可以调用一些以某种方式进行清理的函数。如果我不调用 super().__del__() 是否仍然意味着资源在类销毁时被清除?例如,这段代码是否有可能引入内存泄漏?

class foo(some_library): 
    ... 
 
    def __del__(self): 
        self.proprietary_cleaning_function() 

__init____del__ 之类的函数在重写方式上是否不同?python 中的垃圾回收机制在 __del__ 之后是否起作用?

请您参考如下方法:

不,您需要显式调用基类析构函数以确保 python 将完全删除该对象。

来自 documentation :

If a base class has a __del__() method, the derived class’s __del__() method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance.

另请注意,由于 __del__() 方法仅在您的对象引用计数达到零时调用,因此有一些常见情况可能会阻止对象的引用计数变为零,包括:

circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object on the stack frame of a function that caught an exception (the traceback stored in sys.exc_info() keeps the stack frame alive); or a reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in sys.last_traceback keeps the stack frame alive).

The first situation can only be remedied by explicitly breaking the cycles; the second can be resolved by freeing the reference to the traceback object when it is no longer useful, and the third can be resolved by storing None in sys.last_traceback. Circular references which are garbage are detected and cleaned up when the cyclic garbage collector is enabled (it’s on by default). Refer to the documentation for the gc module for more information about this topic.