首页 > 解决方案 > 发出 PyRun_File 时将 C-API 部分(打印,刷新 = True)函数传输到导入的模块

问题描述

functools.partial(print, flush=True)在调用之前在 C-API 中做一个PyRun_File(请参阅Python C-API 和 PyRun_File: Using "import functools and partial(print, flush=True)")。

打印在__main__模块中有效,但在导入的模块中不可用。

我将尝试创建一个简单的示例来描述该问题:

C代码

Please see full code example in https://stackoverflow.com/questions/67875182/
...
...
PyObject* newPrint = PyObject(partial, args, kwargs);

PyObject* main_module = PyImport_ImportModule("__main__");
PyObject* pdict = PyModule_GetDict(main_module);

PyDict_SetItemString(pdict, "print", newPrint);

FILE* fp = fopen("prg_1.py", "r");
PyObject* pval = PyRun_File(fp, "prg_1.py", Py_file_input, pdict, pdict);

和 Python 文件:

prg_1_func.py

import time

def execute():
    for i in range(5):
        print(i, end=" ")
        time.sleep(1)

prg_1.py

import prg_1_func

if __name__ == "__main__":
    print("Start...")
    prg_1_func.execute()
    print("...End")

__main__由于调用 ,新的打印功能可用PyDict_SetItemString(pdict, "print", newPrint)

但是我怎样才能让它在 prg_1_func.py 中也“可见”呢?

我不能/不想编辑任何 Python 文件!

我想出了一个想法,但不知道它是否可以实现,即导入所有内容并推迟代码的实际执行?

PyObject* newPrint = PyObject(partial, args, kwargs);

PyObject* main_module = PyImport_ImportModule("__main__");
PyObject* pdict = PyModule_GetDict(main_module);

Read all modules that will be imported, without executing the code!

for all modules as MOD do:
    PyDict_SetItemString(pdict, MODname + ".print", newPrint);

FILE* fp = fopen("prg_1.py", "r");
PyObject* pval = PyRun_File(fp, "prg_1.py", Py_file_input, pdict, pdict);

如果其他人遇到相同或类似的问题并设法解决了,您是如何解决的?:o)

标签: pythoncpython-importpython-c-api

解决方案


谢谢你,MisterMiyagi,为我指明了正确的方向!

如果您有类似的问题,请按照第一篇文章中评论部分提供的链接进行操作,希望它也能对您有所帮助。

跨模块全局执行的解决方案print = functools.partial(print, flush=True)似乎是(省略错误检查):

Py_Initialize();

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* newPrint = PyObject_Call(partial, args, kwargs);

PyObject_SetAttrString(builtins, "print", newPrint); <---

PyObject* main_module = PyImport_ImportModule("__main__");
PyObject* pdict = PyModule_GetDict(main_module);

FILE* fp = fopen("prg_1.py", "r");
PyObject* pval = PyRun_File(fp, "prg_1.py", Py_file_input, pdict, pdict);

Py_Finalize();

推荐阅读