【问题标题】:Could overriding Python destructor (__del__) cause memory leaks?覆盖 Python 析构函数 (__del__) 会导致内存泄漏吗?
【发布时间】:2020-12-02 12:26:15
【问题描述】:

我有一个脚本,我在其中使用 API 在云上创建一个对象,并希望在某些情况下在脚本末尾删除它。

class ObjCreator():
   def __init__(self, keep_object: bool):
      self.keep_object = keep_object
      print("init")
   
   def create_object(self):
      print("Created object using API")

   def delete_object(self):
      print("Deleting object using API")

   def __del__(self):
      print("Deleting object using API only if keep_object is False")
      if not self.keep_object:
         self.delete_object()

我在 Python 程序中看到了一些内存泄漏,因此显然 GC 不是完美的(即无法收集的对象)。

我担心重写 del 函数会导致内存泄漏。 那可能吗? 如果是这样,您对不同的优雅解决方案有什么建议吗?

【问题讨论】:

  • 欢迎来到 SO!请注意,您不是重载它,而是覆盖它,也许这有助于谷歌搜索答案
  • 附加提示:所有这些方法都需要添加参数self才能工作——这是对Python显式传递的调用类的引用!
  • 嗨,谢谢 :) 当我为这个问题编写代码的简化时,我不小心错过了自我。固定。

标签: python python-3.x memory-leaks garbage-collection python-3.6


【解决方案1】:

您的直觉是正确的,覆盖__del__ 方法意味着不再自动调用基类的__del__ 方法(尽管我认为这里不太可能发生内存泄漏)。其实文档explicitly mentions this

如果基类有 __del__() 方法,则派生类的 __del__() 方法(如果有)必须显式调用它,以确保正确删除实例的基类部分。

from the CPython repo 的代码示例:

    def __del__(self):
        # ... your cleanup code here ...
        super().__del__()  # call to base class

【讨论】:

  • 这只有在超类实际上有一个__del__ 方法时才重要。特别是object 没有__del__
  • 在您的示例中,该类是一个继承者。为什么在没有超类的情况下它会起作用?
  • 如果你在没有超类 __del__ 可以委托的情况下尝试调用 super().__del__,你会得到一个 AttributeError。
  • @user2357112supportsMonica 这就是我不明白答案的原因。考虑一个向继承者添加新属性的情况——它们不会被 super().__del__() 删除
  • @xjcl - 那为什么要调用 super 方法呢?
猜你喜欢
  • 1970-01-01
  • 2021-03-23
  • 2021-09-25
  • 2014-12-08
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 2011-06-16
相关资源
最近更新 更多