【发布时间】:2021-08-24 17:57:16
【问题描述】:
首先是一个简短的背景:
(1) 在Python3.6中运行这个程序需要等到它结束才能显示结果:
import time
for i in range(5):
print(i, end=" ")
time.sleep(1)
(2) 另一方面,这个程序按我的意愿工作,每秒打印每个值:
import time
import functools
print = functools.partial(print, flush=True)
for i in range(5):
print(i, end=" ")
time.sleep(1)
现在我的问题是:
如何添加
import functools
print = functools.partial(print, flush=True)
在 C 代码中,以便我可以使用 PyRun_File 运行程序 1,但结果就像我在运行程序 2 一样?
我在查找简单易懂的文档和示例时遇到了麻烦,因此希望能得到一些帮助。
这是我尝试过的(省略了错误检查,并且我正在尝试改进的程序中已有的旧代码标记为“//existing”):
Py_Initialize(); //existing
PyObject* functools = PyImport_ImportModule("functools");
PyObject* partial = PyObject_GetAttrString(functools, "partial");
PyObject* builtins = PyImport_ImportModule("builtins");
PyObject* print = PyObject_GetAttrString(builtins, "print");
PyObject* args = PyTuple_New(1);
PyTuple_SetItem(args, 0, print);
PyObject* kwargs = PyDict_New();
PyDict_SetItemString(kwargs, "flush", Py_True);
PyObject_Call(partial, args, kwargs);
PyObject* main_module = PyImport_ImportModule("__main__"); //existing
PyObject* pdict = PyModule_GetDict(main_module); //existing
FILE* fp = fopen("prg_1.py", "r"); //existing
PyObject* pval = PyRun_File(fp, "prg_1.py", Py_file_input, pdict, pdict); //existing
Py_Finalize(); //existing
不幸的是,这并没有像我希望的那样工作,所以任何人都可以发现任何明显的错误,或者可能不是那么明显的错误?
提前感谢您的帮助!
【问题讨论】:
-
对于返回
PyObject*的每个函数,您应该检查返回值是否为NULL。如果是,那么您需要PyErr_Print之类的东西来调查原因。这将帮助您找出我们出了什么问题。这可能是模块搜索路径的问题(但如果你知道它失败的地方会更清楚) -
感谢您的回复,@DavidW。正如我所写的,我故意在发布的代码中省略了错误处理以使其更清晰。实际上,我当然已经检查了 NULL 并且代码在这个意义上“工作”,但它不起作用。
-
PyObject_Call有返回值吗? -
是的。 tp_name 是“functools.partial”,还有其他 tp_-values 似乎一切正常。作为旁注: PyRun_SimpleString("import functools"); PyRun_SimpleString("print = functools.partial(print, flush=True)");然后调用 PyRun_File 似乎有效。
-
我的意思是,仅仅调用
functools.partial(print, flash=True)并不能替换print- 而是返回一个你可以调用的函数。
标签: python c python-c-api