我在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?
答案 0 :(得分:1)
您正在运行子流程而不提供任何stdout或stderr。
在终端中运行时,子进程将继承stdout和stderr,因此它打印的任何内容都会显示与输出混合。
在IDLE中运行时,子进程也继承你的stdout和stderr,但那些不会去任何地方。 IDLE拦截了Python级别的包装器sys.stdout
和sys.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中的工作方式相同。