我有以下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
我在网上找不到类似的问题。你们当中有没有想过在我这里找我?
我错过了有关引用计数管理的内容,或者......
非常感谢
答案 0 :(得分:4)
del a_set
删除对象的引用(局部变量)。在C ++对象中还有另一个引用。这被称为参考循环。循环GC 可以在一段时间后收集它。但是,无法保证何时(或甚至如果)发生这种情况,因此您不应该依赖它 1 。
例如,包含纯__del__
特殊方法are documented的纯Python对象的引用循环不会被释放:
版本3.4中更改:在PEP 442之后,使用
__del__()
方法的对象不再在gc.garbage
中结束。
我不知道Cython's implementation of __dealloc__
是否会触发此行为,但如前所述,无论如何,销毁都不具有确定性。如果你想释放一些资源(例如一块不是Python对象的内存块,一个文件,一个连接,一个锁等),你应该公开一种明确的手动方式(参见{{ 1}}各种对象的方法)。上下文管理器可以简化客户端代码。
免责声明:几乎所有这些都是特定于CPython的。
1 有些人更喜欢将GC视为模拟无限内存可用性的抽象,而不是破坏无法访问的对象的东西。通过这种方法,很明显破坏不是确定性的,甚至不能保证。