PyFile_WriteObject写得太迟了

时间:2018-04-08 14:29:45

标签: python printf cpython

我或多或少有这段代码:

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对象就是一团糟,它也不是真的可行。

1 个答案:

答案 0 :(得分:2)

  

但是,[{1}}不是写PyFile_WriteObject,而是等待与stdout的每次可能的互动

你很可能被Python级别的缓冲所困扰。拨打PyObject_CallMethod(pystdout, "flush", "")可能会解决问题。

  

我真正想要的是复制str(obj)(Python 2版本),然后在printf调用中使用结果。

您正在寻找的PyObject_StrPyUnicode_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);
}