【发布时间】:2017-09-24 01:20:25
【问题描述】:
应用程序的作用:运行子进程并将标准输出实时显示到 Tkinter 文本框小部件。
当我从 PyCharm 运行应用程序时,这非常有效。
当我从终端 ./application.py 运行应用程序时,它不会实时显示,而是会在进程完成后全部显示。
一些细节:
我有一个子进程正在运行(子进程每 1 秒打印出“SPAM”,持续 10 秒):
process = subprocess.Popen(<some file path>, stdout=subprocess.PIPE, universal_newlines=True)
我正在将标准输出打印到 Tkinter 文本框小部件:
for stdout_line in iter(process.stdout.readline, ""):
self.app.pm_textbox.see(tk.END)
self.app.pm_textbox.insert(tk.INSERT, stdout_line)
所以我的问题是什么可能导致从终端和 PyCharm 运行以不同方式显示标准输出数据?
【问题讨论】:
-
它继承了当前的
stdin和stderr。可能在 PyCharm 中这些是管道。不过,我不确定。我认为 PyCharm 对调试有很大的帮助,我没有安装它来测试它的作用。从交互式 shell 运行时,stdin和stderr应该用于终端。尝试将它们覆盖为subprocess.DEVNULL,这样它们在两种情况下都是相同的。 -
@eryksun 很遗憾,这并没有解决问题。
-
您是在 Linux 或其他具有
stdbuf命令的类 Unix 操作系统上开发吗?如果是这样,请尝试将命令更改为['stdbuf', '-oL', filepath]以覆盖默认行缓冲。如果可行,我想知道 PyCharm 在做什么。 -
@eryksun 我正在 Ubuntu 16.04 上开发。添加此命令似乎没有改变任何东西 - PyCharm 仍在工作,从终端启动应用程序没有。
-
这里的症状看起来像是在将输出写入管道之前完全缓冲了输出。典型的缓冲区大小是 4 KiB 或 8 KiB,所以如果你没有那么多数据,缓冲区只会在程序退出时刷新到管道。
stdbuf并不总是有效。它只会改变默认行为,但有些程序会覆盖它。
标签: python python-3.x tkinter subprocess pycharm