简体   繁体   中英

Python C-API and PyRun_File: Using "import functools and partial(print, flush=True)"

First a short background:

(1) When running this program in Python3.6 I need to wait until it ends for the result to be displayed:

import time

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

(2) This program on the other hand works as I would like it to, each value printed every second:

import time

import functools
print = functools.partial(print, flush=True)

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

And now to my question:

How can I add

import functools
print = functools.partial(print, flush=True)

in C code so that I can run program 1 using PyRun_File, but have the results as if I was running program 2?

I have had trouble finding documentation and examples that is straight forward and easy to understand, so I'm hoping for some help.

This is what I have tried (error checking omitted and old code already in the program I'm trying to improve is labeled "//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

Unfortunately this doesn't work as I hoped it would, so can anyone spot any obvious errors, or maybe not so obvious ones?

Thank you in advance for your help!

Thanks to the valuable input from DavidW it now works! Thank you!

(I did although encounter another problem which I will address in a new question.)

With additions the code now looks like this (error checking is still omitted):

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

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

PyDict_SetItemString(pdict, "print", newPrint);

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM