删除对象时无法调用__dealloc__



我有以下c++类:

. h

class ALabSet: public LabSet {
public:
    PyObject *m_obj;
    ALabSet(PyObject *obj);
    virtual ~ALabSet();
    PyObject *GetPyObj();
};

. cpp

ALabSet::ALabSet(PyObject *obj): LabSet() {
    this->m_obj = obj;
    // Provided by "cyelp_api.h"
    if (import_cyelp()) {
    } else {
        Py_XINCREF(this->m_obj);
    }
}

ALabSet::~ALabSet() {
    Py_XDECREF(this->m_obj);
}

PyObject *ALabSet::GetPyObj() {
    return this->m_obj;
}

我在Cython中这样暴露它:

cdef extern from "adapter/ALabSiteSetsManager.h" namespace "elps" :
    cdef cppclass ALabSet:
        ALabSet(PyObject *)
        PyObject *GetPyObj()

cdef class PyLabSet:
    cdef ALabSet *thisptr
    def __cinit__(self):
       self.thisptr = new ALabSet(<PyObject *>self)
    def __dealloc__(self):
       print "delete from PY !"
       if self.thisptr:
           del self.thisptr

我的问题是我不知道如何从Python调用析构函数。下面的代码什么也不做:

a_set = PyLabSet()
del a_set

我在网上找不到类似的问题。你们中有人知道我在这里发生了什么吗?

我错过了一些关于引用计数管理的东西,或者…

Thanks to lot

del a_set删除对对象(局部变量)的引用。还有另一个引用,在c++对象中。这被称为参考循环。循环GC 可以在一段时间后收集它。但是,无法保证何时(甚至如果)发生这种情况,因此您不应该依赖它1

例如,包含具有__del__特殊方法的纯Python对象的引用循环被记录为根本不释放:

在3.4版更改:在PEP 442之后,具有__del__()方法的对象不再以gc.garbage结束。

我不知道Cython的__dealloc__实现是否触发了这种行为,但正如前面所述,销毁无论如何都不是确定的。如果你想释放一些资源(例如一块不是Python对象、文件、连接、锁等的内存),你应该公开一种显式的手动方式(参见各种对象的close方法)。上下文管理器可以简化客户端代码。

免责声明:几乎所有这些都是cpython特有的。

1有些人更喜欢将GC视为模拟无限内存可用性的抽象,而不是破坏不可访问对象的东西。使用这种方法,很明显,销毁不是确定的,甚至不能保证。

相关内容

  • 没有找到相关文章

最新更新