2

我有以下 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

我在网上找不到类似的问题。你们有没有一个想法是出现在我这里?

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

非常感谢

4

1 回答 1

5

del a_set removes a reference to the object (the local variable). There's still another reference, in the C++ object. This is known as a reference cycle. The cycle GC could collect this after a while. However, there is no guarantee when (or even if) this happens, so you should not rely on it1.

For example, reference cycles containing pure Python objects with a __del__ special method are documented to not be freed at all:

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

I don't know whether Cython's implementation of __dealloc__ triggers this behavior, but as outlined before, destruction isn't deterministic anyway. If you want to free some resource (e.g. a block of memory that isn't a Python object, a file, a connection, a lock, etc.) you should expose an explicit way of doing so manually (cf. the close methods of various objects). Context managers can simplify client code doing this.

Disclaimer: Almost all of this is CPython-specific.

1 Some people prefer thinking of GC as an abstraction that simulates availability of infinite memory, rather than something that destroys unreachable objects. With this approach, it becomes quite obvious that destruction is not deterministic and not even guaranteed.

于 2013-04-12T15:12:38.883 回答