C++和Python - 检查PyObject类型失败

2 投票
2 回答
1097 浏览
提问于 2025-04-17 17:08

我有点困惑。我正在尝试把C++和Python结合起来,但这并不是一件简单的事。我没有使用Boost,因为我没能成功编译Boost::Python。不过那是另一个故事。

目前,我在C++中做的事情是:

//set everything up
PyObject* py_main_module = PyImport_AddModule("__main__");
PyObject* py_global_dict = PyModule_GetDict(py_main_module);
PyObject* py_local_dict = PyDict_New();
PyObject* py_return_value;

PyRun_SimpleString(data.c_str()); //runs Python code, which defines functions

//call a function defined by the python code
py_return_value = PyRun_String("test()", Py_single_input, py_global_dict, py_local_dict);

//attempt to check the type of the returned value
if(py_return_value != NULL) {
    //this is the problem: all of these print 0
    cout << PyList_Check(py_return_value) << endl;
    cout << PySet_Check(py_return_value) << endl;
    cout << PyFloat_Check(py_return_value) << endl;
} else {
    cout << "IT WAS NULL?!" << endl;
}

这个Python程序(作为字符串“data”输入到C++程序中):

def test():
    derp = 1.234
    #derp = [1, 2, 3, 4]
    #derp = set([1, 2, 3, 4])
    return derp

现在,问题是类型检查没有正常工作。无论Python函数返回的是浮点数、列表还是集合,它们都返回0。我到底哪里做错了?

如果有人能告诉我为什么调用PyRun_String会在控制台打印返回值,那就更好了。这真的很烦人。

2 个回答

2

Py_single_input 改成 Py_eval_input 似乎可以解决这两个问题。

前者把字符串当成解释器循环的一部分来处理,而后者则是计算一个单独的表达式,并返回一个对象给你。(我不太确定前者的返回值是什么意思,但它不是表达式的值。)

编辑:刚刚测试了一下,根据 nneonneo 下面的回答,使用 Py_single_input 的结果确实是 Py_None

3

来自文档的内容:

int Py_eval_input

这是Python语法中用于单独表达式的起始符号;可以和Py_CompileString()一起使用。

int Py_file_input

这是Python语法中用于从文件或其他来源读取的一系列语句的起始符号;同样可以和Py_CompileString()一起使用。这个符号适合用来编译任意长度的Python源代码。

int Py_single_input

这是Python语法中用于单个语句的起始符号;也可以和Py_CompileString()一起使用。这个符号用于交互式解释器循环。

Py_single_input会把字符串当作一个语句来执行。语句本身并不会返回任何结果,所以你从PyRun_String得到的结果会是None。如果想要把字符串当作表达式来计算并得到结果,应该使用Py_eval_input

撰写回答