PyFunctionObject如果在PyTup中设置了Py\u Finalize中的项目,则会使程序崩溃

2024-09-30 06:21:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要通过python文件获得函数名和签名的列表。 Python函数inspect.signature可以获取函数签名。 但是inspect.signature需要一个函数对象(PyFunctionObject)。 inspect.getmembers可以返回这样的对象。 但是如果我将PyFunctionObject设置为PyTuple中的项,当Py_Finalize被执行时,我会得到一个错误。 另外,我正在使用Qt

所以行PyTuple_SetItem(pFuncLink_arg, 0, pGetmember_tupleList);结果错误

C级ode:.

PyObject *pName, *pModule;
PyObject *pInspect_module_name, *pInspect_module;
PyObject *pGetmember_function, *pGetmember_call_args, *pGetmembers_reply, *pGetsignature_function, *pGetmember_itemList, *pGetmember_tupleList;
PyObject *pFuncName, *pFuncLink_arg, *pFuncSign;

Py_Initialize();

QFileInfo fileInfo(QFile("X:/Projects/p-text.py"));
QString absPath = fileInfo.absolutePath();

QString fileName = fileInfo.baseName();

PyObject* sysPath = PySys_GetObject((char*)"path"); 
PyObject* programName = PyUnicode_FromString(absPath.toAscii());
PyList_Append(sysPath, programName);

pName = PyUnicode_FromString(fileName.toLatin1());
pModule = PyImport_Import(pName);
Py_DECREF(pName);

if (pModule != NULL){
    pInspect_module_name = PyUnicode_DecodeFSDefault("inspect");
    pInspect_module = PyImport_Import(pInspect_module_name);
    pGetmember_function = PyObject_GetAttrString(pInspect_module, "getmembers");    
    pGetsignature_function = PyObject_GetAttrString(pInspect_module, "signature");

    pGetmember_call_args = PyTuple_New(1);
    PyTuple_SetItem(pGetmember_call_args, 0, pModule);
    pGetmembers_reply = PyObject_CallObject(pGetmember_function, pGetmember_call_args);

    if (pGetmembers_reply){
        Py_ssize_t const num_args = PyList_Size(pGetmembers_reply);
        for (Py_ssize_t i = 0; i < num_args; ++i){
            pGetmember_itemList = PyList_GetItem(pGetmembers_reply, i);
            pGetmember_tupleList =  PyTuple_GetItem(pGetmember_itemList, 1);

            if (PyFunction_Check(pGetmember_tupleList)){
                pFuncName =  PyTuple_GetItem(pGetmember_itemList, 0);
                QString funcName = PyObjectToString(pFuncName);
                    Py_DECREF(pFuncName);

                pFuncLink_arg = PyTuple_New(1);
                PyTuple_SetItem(pFuncLink_arg, 0, pGetmember_tupleList);

                pFuncSign = PyObject_CallObject(pGetsignature_function, pFuncLink_arg);

                if (pFuncSign == NULL) {
                    if (PyErr_Occurred()) {
                        PyErr_Print(); 
                    }
                    return;
                }

                QString funcSign = PyObjectToString(pFuncSign);

                Py_DECREF(pFuncSign);

                cout<<funcSign.toStdString()<<endl;
            }

            Py_DECREF(pGetmember_tupleList);
            Py_DECREF(pGetmember_itemList);
        }
    }
    Py_DECREF(pInspect_module_name);
    Py_DECREF(pInspect_module);
    Py_DECREF(pGetmember_function);
    Py_DECREF(pGetsignature_function);
    Py_DECREF(pGetmember_call_args);
}
else {
    PyErr_Print();
}

Py_Finalize();

Py_Finalize()抛出一个错误 “项目\u name.exe已触发断点”


Tags: namepyargargsfunctioncallmodulepyobject
1条回答
网友
1楼 · 发布于 2024-09-30 06:21:26

参考计数错误

^{}返回一个“借用的引用”。你不拥有pGetmember_tupleList

PyTuple_SetItem(在同一个链接中找到它…)“窃取引用”,即假设您在调用前拥有pGetmember_tupleList,但在调用后不拥有它

您需要在获得它之后添加一个Py_INCREF(pGetmember_tupleList)


pFuncName中有一个单独的、相关的引用计数错误—您定义了一个不属于自己的借用引用。我怀疑这里可能还有其他引用计数错误


你也没有错误检查;几乎每个Python调用之后都应该检查是否引发了异常(通常是针对NULL指针)

相关问题 更多 >

    热门问题