我或多或少有这段代码:
PyObject* py_list(PyObject* obj) {
printf("py_list: %p, ", obj);
PyObject* pystdout = PySys_GetObject("stdout");
PyFile_WriteObject(obj, pystdout, Py_PRINT_RAW);
printf("\n");
printf("py_list: %p\n", pystdout);
if (obj == NULL) {
return PyList_New(0);
}
PyObject* result = PyList_New(1);
PyList_SetItem(result, 0, obj);
printf("py_list returns: %p, ", result);
PyFile_WriteObject(result, pystdout, Py_PRINT_RAW);
printf("\n");
return result;
}
我真正想要的是复制str(obj)
(Python 2版本),然后在printf
调用中使用结果。我找不到一个理智的API来调用这样的东西。所以,PyFile_WriteObject
是我能找到的最接近的...但是,它不会写入stdout
,而是等待,直到与stdout
的每个可能的交互在C中完成,然后它才打印出来它原本应该......
我已经看过Cython为print(obj)
或str(obj)
这样的代码生成了什么,我想把头发拉出来,它太复杂了。实际上,我需要的是能够打印出Python对象以进行调试。我也尝试过GDB方式,但是当你从GDB的角度看它们时,Python对象就是一团糟,它也不是真的可行。
答案 0 :(得分:2)
但是,[{1}}不是写
PyFile_WriteObject
,而是等待与stdout
的每次可能的互动
你很可能被Python级别的缓冲所困扰。拨打PyObject_CallMethod(pystdout, "flush", "")
可能会解决问题。
我真正想要的是复制
str(obj)
(Python 2版本),然后在printf
调用中使用结果。
您正在寻找的PyObject_Str
与PyUnicode_AsUTF8
结合使用。这允许这样的事情:
printf("py_list returns: %s\n", PyUnicode_AsUTF8(PyObject_Str(result)));
这会泄漏__str__
返回的字符串,如果PyObject_Str
引发则会崩溃;正确的版本可能如下所示:
void print_obj(PyObject *o) {
PyObject *o_str = PyObject_Str(o);
if (!o_str) {
PyErr_Print();
return;
}
printf("%s\n", PyUnicode_AsUTF8(o_str));
Py_DECREF(o_str);
}