我的嵌入式 python 标准输出在哪里?

Posted

技术标签:

【中文标题】我的嵌入式 python 标准输出在哪里?【英文标题】:Where does my embedded python stdout go? 【发布时间】:2015-09-17 00:07:00 【问题描述】:

考虑以下MWE:

#include <Python.h>
#include <stdio.h>

int main(void) 
  printf("Test 1\n");
  Py_Initialize();
  printf("Test 2\n");
  PyRun_SimpleString("print('Test 3')");
  printf("Test 4\n");
  return 0;

当我正常编译并运行它时,我得到了预期的输出:

$ ./test
Test 1
Test 2
Test 3
Test 4

但是当我重定向输出时,我从 python 代码中什么也得不到:

$ ./test | cat
Test 1
Test 2
Test 4

发生了什么?更重要的是,如何让我的 python 输出像预期的那样写入标准输出?

【问题讨论】:

有趣的是,如果你将'import sys; sys.stdout.flush()' 添加到 Python 脚本,你会得到重定向的输出,但 before 其他所有内容。 【参考方案1】:

stdout 引用终端时,输出是行缓冲的,否则是块或完全缓冲的,直到块满才输出。

若要在stdout 引用非终端时缓冲输出行,请使用setvbuf 设置模式 你必须调用Py_Finalize() 来让libpython 关闭它的I/O 句柄。

#include <Python.h>
#include <stdio.h>

int
main(int argc, char **argv) 
    //setlinebuf(stdout);
    setvbuf(stdout, NULL, _IOLBF, 0);
    printf("Test 1\n");
    Py_Initialize();
    printf("Test 2\n");
    PyRun_SimpleString("print('Test 3')");
    Py_Finalize();
    printf("Test 4\n");
    return 0;

【讨论】:

你可以在 Python 中调用sys.stdout.flush()。调用 Py_Finalize() 对于他的用例可能不是故意的。 @tynn 如果你不调用Py_Finalize() 输出是乱序的,那是 Python 的第一个。 啊...当然,现在一切都很明显了 :) 谢谢!【参考方案2】:

在当前的 Python 中,你可以使用Py_UnbufferedStdioFlag

【讨论】:

以上是关于我的嵌入式 python 标准输出在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中流式传输标准输入/标准输出

你如何告诉 Spring Boot 将嵌入式 Tomcat 的访问日志发送到标准输出?

Python Popen 在标准输入上发送到进程,在标准输出上接收

从子进程中实时捕获标准输出

如何读取子进程标准输出的第一个字节,然后在 Python 中丢弃其余字节?

如何读取子进程标准输出的第一个字节,然后在 Python 中丢弃其余字节?