其他分享
首页 > 其他分享> > c – 删除对象时,我无法调用__dealloc__

c – 删除对象时,我无法调用__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

我在网上找不到类似的问题.你们当中有没有想到我的意思?

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

非常感谢

解决方法:

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

例如,包含纯Python对象和__del__特殊方法are documented的引用循环根本不会被释放:

Changed in version 3.4: Following PEP 442, objects with a __del__() method don’t end up in gc.garbage anymore.

我不知道Cython’s implementation of __dealloc__是否触发了这种行为,但如前所述,无论如何,破坏都不是确定性的.如果你想释放一些资源(例如一块不是Python对象的内存块,一个文件,一个连接,一个锁等),你应该公开一种明确的手动方式(参见close方法)各种物件).上下文管理器可以简化客户端代码.

免责声明:几乎所有这些都是CPython特有的.

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

标签:python,c,destructor,cython
来源: https://codeday.me/bug/20190927/1824603.html