python - 在另一个应用程序中嵌入 python 时,如何导入或调用子模块中的函数(即 scipy.optimize.nnls)?

标签 python c++ numpy python-embedding

首先我要重申这个问题:当使用 python docs 将 Python 嵌入到 C/C++ 应用程序中时和其他资源。我发现您可以使用导入模块

PyObject *pName = PyUnicode_FromString((char*)"scipy");
PyObject *pModule = PyImport_Import(pName); 

但如果我尝试导入“scipy.optimize”
PyObject *pName = PyUnicode_FromString((char*)"scipy.optimize");
PyObject *pModule = PyImport_Import(pName); 

那么程序初始化失败pModule .如果我再试一次
PyObject *pName = PyUnicode_FromString((char*)"scipy");
PyObject *pModule = PyImport_Import(pName); 
pFunc = PyObject_GetAttrString(pModule, (char*)"optimize.nnls");

我放的地方optimize在函数名中它无法初始化 pFunc .如何在子模块中导入或调用函数,即如何调用函数 scipy.optimize.nnls?

接下来,我将列出我的代码以防万一:
/* Relelvant imports
    #include <Python.h>
    #include <numpy/arrayobject.h> 
*/

void nnls::update(const vec& x, const vec& y)
{
    mat B;
    vecToGslVec(x, gslx);
    generateX(X, gslx);
    A = gslMatToMat(X);
    B = A.transpose();
    long double *c_out;

    Py_Initialize();
    PyObject *pName = PyUnicode_FromString((char*)"scipy"); //Issue Here
    check(pName, "pName not initializes.");

    PyObject *pModule = PyImport_Import(pName);
    check(pModule, "pModule not initializes.");

    PyObject *pFunc, *pArgs, *pResult;
    PyArrayObject *pNpArray;

    npy_intp Adims[2]; Adims[0] = A.rows(); Adims[1] = A.cols();
    npy_intp bdim[1];  bdim[0] = y.size();

    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, (char*)"optimize.nnls"); //Issue Here
        check(pFunc, "pFunc not initializes.");

        /*program never advances past this point unless I remove this check, 
        in which case I get a segfault, because pFunc is not initialized.*/

        if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_Pack(2,
                PyArray_SimpleNewFromData(2, Adims, NPY_FLOAT, B.data()),
                PyArray_SimpleNewFromData(1, bdim , NPY_FLOAT, \
                    const_cast<double*> (y.data()))
            );
            check(pArgs, "pArgs not initializes.");
            pResult = PyObject_CallObject(pFunc, pArgs);
            check(pResult, "pResult not initializes.");
            pNpArray = reinterpret_cast<PyArrayObject*>(pResult);
            log_info("not PyArray cast");
        }
        Py_DECREF(pFunc);
    }
    Py_DECREF(pModule);
    Py_DECREF(pArgs);
    c_out = reinterpret_cast<long double*>(PyArray_DATA(pNpArray));
    for(size_t i=0; i<order; i++){
        gsl_vector_set(gslc, i, c_out[i]);
    }
    if (pResult != NULL) Py_DECREF(pResult); Py_DECREF(pNpArray);
    Py_Finalize();
}

同样,我的问题在于
PyObject *pModule = PyImport_Import(pName);


pFunc = PyObject_GetAttrString(pModule, (char*)"optimize.nnls");

如果我设置
pName = PyUnicode_FromString((char*)"scipy.optimize"); 

或者
pFunc = PyObject_GetAttrString(pModule, (char*)"optimize.nnls");

代码无法在这些点初始化这些变量。

所以最后一次重申我的问题我如何导入模块 scipy.optimize或调用函数optimize.nnls在这种情况下?谢谢。我希望它不会太困惑,如果让我知道,我会澄清。

最佳答案

像很少使用的内置 __import__功能,当你 PyImport_Import姓名 scipy.optimize ,导入系统会加载 scipy.optimize模块,但它返回 scipy而不是 scipy.optimize .您需要沿着属性链向下到 scipy.optimize.nnls :

PyObject *scipy = PyImport_Import(pName);
PyObject *optimize = PyObject_GetAttrString(scipy, "optimize");
PyObject *nnls = PyObject_GetAttrString(optimize, "nnls");

一如既往,别忘了Py_DECREF完成后您拥有的任何引用资料。这包括像 pName 这样的东西。 .

关于python - 在另一个应用程序中嵌入 python 时,如何导入或调用子模块中的函数(即 scipy.optimize.nnls)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37445397/

相关文章:

python - 在 Pandas 数据框上应用条件以过滤数组时的FutureWarning

python - 使用 scrapy 从 200k 域中提取文本

python - 面向对象的函数参数以更改变量

c++ - 按值搜索 map

c++ - 我想在 C++ 中查看 hash_map 示例

python - 检查不同的numpy数组中的相同行

python - 将 mask 阵列2d应用于3d

java - Python工具/软件包,可根据问题生成测验并提供文本文件中的选项

python - 重复的Django查询集?

c++ - + 运算符,类类型和内置类型之间的区别?