Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在将python嵌入另一个应用程序时,如何导入或调用子模块中的函数(即scipy.optimize.nnls)?_Python_C++_Numpy_Python Embedding - Fatal编程技术网

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

在将python嵌入另一个应用程序时,如何导入或调用子模块中的函数(即scipy.optimize.nnls)?,python,c++,numpy,python-embedding,Python,C++,Numpy,Python Embedding,首先,我要重申一个问题:在使用和其他资源将Python嵌入C/C++应用程序时。我发现您可以使用 PyObject *pName = PyUnicode_FromString((char*)"scipy"); PyObject *pModule = PyImport_Import(pName); 但是如果我尝试导入“scipy.optimize” 然后程序无法初始化pModule。如果我再试一次 PyObject *pName = PyUnicode_FromString((char*)"s

首先,我要重申一个问题:在使用和其他资源将Python嵌入C/C++应用程序时。我发现您可以使用

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

然后程序无法初始化
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();
}

如果我设定

pName = PyUnicode_FromString((char*)"scipy.optimize"); 

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


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

就像很少使用的内置
\uuuuuuuuuuuuu导入
函数一样,当您导入名称
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

首先,我从未使用过
PyImport\u Import()
。我一直使用
PyImport\u ImportModule()
,它采用
const char*
arg而不是
PyObject*
。这样可以在代码中保存一些步骤

PyObject *pModule = PyImport_ImportModule("scipy.optimize");
PyObject *pFunc = PyObject_GetAttrString(pModule, "nnls");
这就是我在我编写的代码中所做的事情
PyImport\u ImportModule()
处理包层次结构
PyObject\u getAttrString()
不知道如何处理点


我从来没有使用过
PyImport\u Import()
,所以我不知道它的行为会如何改变。谢谢,我在看过文档后确实尝试过这个方法,但一定是用错了。谢谢你,你的两个答案都很有帮助。
PyObject\u GetAttrString(pModule,(char*)“optimize.nnls”)
就像在python中尝试
getattr(模块,“optimize.nnls”)
。您需要
PyObject\u GetAttrString(PyObject\u GetAttrString(pModule,“optimize”),“nnls”)
pName = PyUnicode_FromString((char*)"scipy.optimize"); 
pFunc = PyObject_GetAttrString(pModule, (char*)"optimize.nnls");
PyObject *scipy = PyImport_Import(pName);
PyObject *optimize = PyObject_GetAttrString(scipy, "optimize");
PyObject *nnls = PyObject_GetAttrString(optimize, "nnls");
PyObject *pModule = PyImport_ImportModule("scipy.optimize");
PyObject *pFunc = PyObject_GetAttrString(pModule, "nnls");