CPython:在没有自定义“tp_dealloc”的 C 定义静态类型中使用“tp_finalize”

问题描述 投票:0回答:1

PEP 442 向 Python 类型定义引入了

tp_finalize
回调(作为 Python 类的
__del__
函数的一对一等效项),并建议将其用于任何重要的破坏。

官方 API 文档指出:

如果设置了

tp_finalize
,解释器在完成实例时会调用它一次。

但是,对于没有定义自定义释放器(直接或从其基类继承)的 C 定义的静态 Python 类型来说,情况似乎并非如此。据我了解:

  • 没有自定义
    tp_dealloc
    的静态类型将从基本 Python 类型 (
    PyBaseObject_Type
    ) 继承释放器,即
    object_dealloc
    • object_dealloc
      非常简单,它只是调用给定对象类型的
      tp_free
    • 因此,永远不会为这些对象调用
      tp_finalize
  • 使用
    PyType_FromSpec
    和类似方法在堆上定义的类型将默认继承
    subtype_dealloc
    释放器。
    • subtype_dealloc
      更复杂,会调用
      PyObject_CallFinalizerFromDealloc

问题

假设我正确理解了 CPython 当前的行为:

  • 预计
    PyBaseObject_Type
    解除分配器不会调用
    tp_finalize
    吗?
  • 如果是,导致此异常的原因是什么?
  • 那么将
    subtype_dealloc
    暴露为 C 定义的静态类型的通用 dealloc 回调是否有意义?
python python-3.x destructor cpython python-c-api
1个回答
0
投票

我们在 Python 讨论频道上问问题结束了。

请点击上面的链接了解详情。 TL;DR:当 PEP 442 实施时(或之后),这可能是一个被忽视的方面。然而,尝试修复它可能比当前问题更麻烦,并且使用

tp_dealloc
而不是
tp_finalize
应该没问题且安全,只要
self
本身没有调用 python 代码即可。

© www.soinside.com 2019 - 2024. All rights reserved.