Python C API: 如何刷新标准输出和标准错误?

Python C API: how to flush stdout and stderr?

当用 C 代码编写 Python 扩展时,可以使用函数 PySys_WriteStdoutPySys_WriteStderr 打印到 python 标准输出和标准错误流,这有效类似于 C 的 printf (https://docs.python.org/3/c-api/sys.html).

但是在通过这些函数打印了一些东西之后,我该如何刷新相应的输出流呢?例如。像 C 的 fflush(stdout)fflush(stderr).

根据PySys_WriteStdout() call which simply calls sysmodule.sys_write(_Py_Identifier *key, FILE *fp, const char *format, va_list va)

,你可以根据我的记忆做两件事
  • unset the sys.stdout,因此您将访问原始 STDOUT,而不仅仅是 Python 的包装器,为此您应该能够使用标准 C flushing
  • 获取sys.stdout的引用并直接刷新

可选,只需将 PYTHONUNBUFFERED 设置为环境变量,但它不那么灵活,并且默认情况下不存在于系统中

对于 sys.stdout 刷新,您也可以使用 sys.stdout 参考中的 PySys_GetObject(const char *name) directly and then call the io.IOBase.flush()

PySys_GetObject("__stdout__") according to the implementation in the pylifecycle.init_sys_streams(PyThreadState *tstate)

或者如果你想过着危险的生活,只需拉动私人API(_PySys_GetObjectId(&PyId_stdout))来利用,就像CPython一样。它被定义为 in bltinmodule.c via _Py_IDENTIFIER(varname).

Here is CPython 如何通过其 pylifecycle.flush_std_files() 函数进行刷新。