从Python解释器中调用一个方法

3
1个回答

0

好的,这可能需要更长一点时间。请注意,我基本上忽略了所有“通常”的错误检查 - 几乎任何Python方法都可能返回NULL,在这种情况下,您应该优雅地处理它。我展示了“不寻常”的部分,检查给定对象是否可调用。请注意,如果对象指针为NULL,则PyDECREF会失败,而Py_XDECREF则不会。现在来看代码 - 可能有更好的方法来解决所有这些问题,但对我来说,这个方法很好用,遗憾的是文档极其缺乏。

C++ 代码:

#include <Python.h>

static PyThreadState *mainstate;

void initPython(){
    PyEval_InitThreads();
    Py_Initialize();
    mainstate = PyThreadState_Swap(NULL);
    PyEval_ReleaseLock();
}

void exitPython(){
    PyEval_AcquireLock();
    PyThreadState_Swap(mainstate);
    Py_Finalize(); 
}

void callScript() {
    PyGILState_STATE gstate = PyGILState_Ensure();
    PyObject *pName = PyUnicode_FromString("Startup"); 
    PyObject *pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    PyObject *pFunc = PyObject_GetAttrString(pModule, "startup");
    if (pFunc && PyCallable_Check(pFunc)) {
        PyObject *arglist = Py_BuildValue("(u)", "TestScript");
        PyObject *result = PyObject_CallObject(pFunc, arglist);
        Py_DECREF(arglist);
        // Now you have the returned object of the function - do something with it.
        // In our case that's None, but you should extend the python scrip to return
        // whatever you need - see the profiler API.
        Py_DECREF(result);          
    }
    Py_XDECREF(pFunc);  // XDECREF does not fail if pointer is NULL.
    Py_DECREF(pModule);
    PyGILState_Release(gstate); 
}

int main() {
    printf("Start.\n");
    initPython();
    callScript();
    exitPython();
    printf("Exit.\n");
    return 0;
}

你的特定脚本总是被调用,将其更改为以有用的方式返回所有所需数据 - 目前我们只使用cProfile.run()打印一些信息:

Startup.py
import cProfile

def startup(module_name):
    print("Start script")
    cProfile.run("import " + module_name)
    print("Finished script")

最后执行的简单脚本:

TestScript.py
sum = 0
for i in range(10000):
    sum += i

谢谢 Voo,我需要更仔细地阅读这个,但是你帮了我很大的忙。再次感谢 :) - easythrees
1
我从一些相当复杂的代码中拼凑出来的,现在已经是凌晨3点了,所以我希望我没有犯任何错误。该睡觉了 :) - Voo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接