2017-07-05 23 views
1

我正在使用Python C API在我的C++程序中,并且我注意到了一件奇怪的事情。为什么PyImport_ImportModule返回PyObject *的引用数为3而不是1

虽然我在我的电脑上调试器中运行一个简单的程序是这样的:

int main(int argc, const char * argv[]) { 

    Py_Initialize(); 
    PyObject* scipy_stats_module = PyImport_ImportModule("scipy.stats"); // importing "scipy.stats" module 

    Py_DecRef(scipy_stats_module); 

    if (Py_FinalizeEx() < 0) { 
     PyErr_Print(); 
     exit(-1); 
    } 

    return 0; 

} 

我见过的scipy_stats_moduleob_refcnt属性,它的创建后,并呼吁Py_DecRef前右,被设置为3,而我期待它等于1.

有人能帮我理解为什么会发生这种情况?这是我的代码问题还是正常?我应该拨打Py_DecRef三次还是一次?

谢谢!

P.S.我使用Xcode 8.3.3作为IDE并在我的PC上使用macOS调试器10.12.5

+0

模块导入(缓存)后,一个引用存储在'sys.modules'字典中。但我不确定其他来自哪里。 – freakish

+0

@freakish好的,所以它不是我想要的代码的问题。但是,每次我使用PyImport'或类似'PyObject_GetAttrString'时应该调用'Py_DecRef'三次呢?我觉得很奇怪。 – jackscorrow

+0

我不这么认为。你应该只调用一次'Py_DecRef'。完成后使用它。 'Py_Finalize'应该照顾其余的。但也许你应该等待别人来确认它。 – freakish

回答

1

您不拥有对新模块的唯一引用。在这种情况下,识别其他参考很简单 - 一个是sys.modules['scipy.stats'],另一个是scipy模块对象的stats属性 - 通常,它不关心模块可能具有的其他引用。

当您清除对模块的引用时,您应该只有一次Py_DECREF,因为您只清除一个引用,即您自己的引用。其他参考文献仍然存在,仍然需要在refcount中进行说明。

相关问题