【问题标题】:Python IDLE script does not show output of subprocess but cmd.exe doesPython IDLE 脚本不显示子进程的输出,但 cmd.exe 显示
【发布时间】:2014-11-22 17:28:14
【问题描述】:

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

我有 2 个 Python 脚本:

脚本.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?

【问题讨论】:

    标签: python shell windows-7 python-idle


    【解决方案1】:

    您正在运行子进程而不提供任何标准输出或标准错误。

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

    在 IDLE 中运行时,子进程将继承您的 stdout 和 stderr,但它们不会去任何地方。 IDLE 拦截 Python 级别的包装器 sys.stdoutsys.stderr,*,因此您从 Python 中打印到它们的任何内容都将最终出现在 GUI 窗口中,但任何进入 real stdout 或 stderr 的内容——就像你运行的任何继承你的流的子进程的输出一样——只是无处可去。**

    最简单的解决方法是从子进程中捕获 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 上是如何工作的。但无论如何,这对你没有帮助。

    【讨论】:

      【解决方案2】:

      我验证了abamert 的更改在Win7 上的2.7 中有效,空闲从图标正常启动。小故障是“打印输出”插入了一个额外的空白行。这很容易通过使 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 调用更改为来解决此问题

      print(out.decode(), end='')
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-26
        • 2022-06-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多