Python IDLE脚本不显示子进程的输出,但cmd.exe的输出

时间:2014-09-28 02:04:50

标签: python shell windows-7 python-idle

我在Windows 7上使用Python 2.7.6和IDLE。

我有2个Python脚本:

script.py:

import subprocess, os, sys

print("hello 1")

mypath = os.path.abspath(__file__)
mydir = os.path.dirname(mypath)
start = os.path.join(mydir, "script2.py")

subprocess.call([sys.executable, start, "param"])

print("bye 1")

和前一个脚本调用的script2.py:

import sys

print "hello 2"

print (sys.argv[1])

print "bye 2"

如果我使用cmd.exe shell运行script.py,我会得到预期的结果:

C:\tests>python ./script.py
hello 1
hello 2
param
bye 2
bye 1

但是如果我用IDLE编辑器打开script.py并用F5运行它,我会得到这个结果:

>>> ================================ RESTART ================================
>>> 
hello 1
bye 1
>>> 

为什么子脚本没有写入IDLE Python shell?

2 个答案:

答案 0 :(得分:1)

您正在运行子流程而不提供任何stdout或stderr。

在终端中运行时,子进程将继承stdout和stderr,因此它打印的任何内容都会显示与输出混合。

在IDLE中运行时,子进程继承你的stdout和stderr,但那些不会去任何地方。 IDLE拦截了Python级别的包装器sys.stdoutsys.stderr,*所以你在Python中打印它们的任何东西都会在GUI窗口中结束,但是任何转到 real 的东西stdout或stderr-like你运行的任何继承你的流的子进程的输出 - 只是无处可去。**

最简单的解决方法是从子进程中捕获stdout和stderr并自己打印它们。例如:

out = subprocess.check_output([sys.executable, start, "param"],
                              stderr=subprocess.STDOUT)
print out

* IDLE比看起来更复杂。它实际上为GUI窗口和运行代码运行单独的进程,通过套接字进行通信。 IDLE为您的脚本提供的sys.stdout(以及其他人也是如此)不是file个对象,它是一个自定义文件类对象,可以将每个write重定向到GUI过程通过套接字调用远程过程。

**实际上,如果您从终端启动IDLE而不是双击其图标,则子进程的输出可能最终那里。我不确定它在Windows上是如何工作的。但无论如何,这对你没有帮助。

答案 1 :(得分:0)

我验证了在Win7上,abamert的更改工作在2.7,Idle正常从图标开始。轻微的故障就是“打印出来'插入一个额外的空白行。通过将print打印为将来导入和使用end参数的功能,可以轻松更改此内容。

from __future__ import print_function
...
print(out, end='')

使用Python 3,还有一个问题是' out'是字节而不是str,因此它打印为

b'hello 2\r\nparam\r\nbye 2\r\n'

由于您的输出全部是ascii,因此可以通过将打印调用更改为

来解决此问题
print(out.decode(), end='')

结果程序在2.7和3.x中的工作方式相同。