26

运行简单的 .py 或 .pyw python 文件会导致python.exe显示在任务管理器下。

python myApp.py
python myApp.pyw

但是,当我们尝试在不使用控制台的情况下运行它时,脚本似乎没有运行,也没有python.exepythonw.exe出现在任务管理器下

pythonw myApp.pyw
pythonw myApp.py

我们如何解决问题?系统正在运行 Python 2.7.8 x64。

4

7 回答 7

36

tl;博士

  • 要进行故障排除,请在调用时使用输出重定向:

    pythonw myApp.py 1>stdout.txt 2>stderr.txt
    

这将捕获 stdout 输出,例如 from print(), in filestdout.txt和 stderr 输出(例如来自未处理的异常), in file stderr.txt;来自 PowerShell,使用
cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt)。
请注意,重定向 stdout 的行为实际上可能会使您的脚本再次工作如果它失败的唯一原因pythonw是使用print(在 Python 2.x 中 - 见下文)。
警告:这种输出重定向技术在直接调用脚本时似乎不起作用而不是通过将脚本文件路径传递给)。如果您知道原因和/或它是否对您有用,请告诉我。*.pywpythonw.exe

  • 修复您的脚本

将以下内容放在运行pythonw.exe的任何 Python 2.x 或 3.x 脚本的顶部:

import sys, os
if sys.executable.endswith("pythonw.exe"):
  sys.stdout = open(os.devnull, "w");
  sys.stderr = open(os.path.join(os.getenv("TEMP"), "stderr-"+os.path.basename(sys.argv[0])), "w")

这可确保在使用以下命令运行脚本时pythonw.exe

  • print()调用和显式调用sys.stdout()被有效地忽略(无操作)。
  • Stderr 输出,包括未处理的致命异常,被发送到文件 %TEMP%\stderr-<scriptFileName>%TEMP%是一个标准的 Windows 环境变量,它指向当前用户的临时文件文件夹。

换句话说:有了上面的代码,当你的脚本在调用时静默失败后检查文件%TEMP%\stderr-<scriptFileName>pythonw.exe

如需解释,请继续阅读。


在 Windowspythonw.exe上,用于启动 GUI/no-UI-at-all 脚本,这意味着标准输入和输出流 - sys.stdinsys.stdoutsys.stderr不可用。

这有两个讨厌的副作用

  • 使用print()-sys.stdout默认情况下的目标 -在 Python 2.x 中会导致异常
    • 此问题已在 Python 3.x 中得到修复。
  • 任何未处理的异常(包括print()2.x 中触发的异常)都会导致脚本静默中止
    • 默认情况下会发送异常错误消息sys.stderr,这在这种情况下是不可用的。

上面的代码通过以下方式解决了这些问题:

  • 将 stdout 输出发送到 null 设备,有效地忽略任何输出到的尝试sys.stdout- 无论是通过print().

  • 将所有 stderr 输出发送到临时文件。


Python 2.x 和 Python 3.x 的区别:

当使用pythonw.exesys.stdinsys.stdout和运行脚本时sys.stderr

  • 在 Python 2.x中:具有无效的文件描述符
    • 尝试写入or时的最终结果是以下异常:sys.stdoutsys.stderrIOError: [Errno 9] Bad file descriptor
    • 陷阱:由于输出缓冲,此异常可能在您输出 4K 字节之前不会出现pythonw.exe您可以通过调用with立即激发它-u(对于无缓冲输出)。
    • print()盲目地尝试sys.stdout(默认情况下),所以它迟早会引发这个异常。
  • 在 Python 3.x中:设置为None
    • 这与 3.xprint()函数在发现is时执行无操作(什么都不做)进行补充,因此默认情况下可以安全地使用语句 -当运行时它们将被忽略sys.stdoutNoneprint()pythonw.exe
    • 但是,随之而来的是尝试使用sys.stdout.write()并且sys.stderr.write()仍然导致异常。

有关更多背景信息,请参见此处

于 2015-05-18T18:14:38.857 回答
5

尝试将该行添加import sys; sys.stderr = open("errlog.txt", "w")myApp.py. 然后查找errlog.txt回溯或任何其他错误消息。

于 2014-07-19T02:37:03.007 回答
2

我在自己的脚本上遇到了同样的问题,发现当添加罗斯答案的输出时,脚本实际上会运行。

似乎由于某种原因重定向输出解决了这个问题。由于我对将输出写入磁盘不感兴趣,因此我将其写入/dev/null(或等效平台):

if ( sys.platform == 'win32' and sys.executable.split( '\\' )[-1] == 'pythonw.exe'):
    sys.stdout = open(os.devnull, 'w')
    sys.stderr = open(os.devnull, 'w')

if 语句确保它仅在脚本从pythonw.exe. 我不确定它是否相关,但在其他导入(包括 eg import logging)之前这样做很重要。

于 2014-10-01T19:02:47.923 回答
1

我遇到了类似的问题。

通过写入日志文件逐步调试后,我发现pythonw.exe在尝试使用调用的语句后崩溃:sys.stdout.write()。事实证明,当使用 pythonw.exe 运行时,sys.stdout 为无。

如果您正在使用 sys.stdout/stderr/stdin 的功能,并打算将您的程序与 pythonw.exe 一起使用,添加“无”检查是个好主意。

于 2015-01-27T18:05:51.430 回答
-1

我不确定我是否理解您的问题,但我认为这是您需要知道的

您需要右键单击 py 或 pyw 文件并选择打开方式...找到 python.exe(可能是 C:\Python27\python.exe)..选中始终打开的框...现在您可以加倍如果要运行它,请单击它

(通常安装程序会为您设置这个......)

于 2014-07-18T23:34:42.397 回答
-1

这是一个旧答案,但我也想在这里留下我的解决方案:

  • 打开 CMD(是否具有提升的权限 - 取决于您的需要)
  • 切换到 .py / .pyw 脚本的目录- 这很重要
  • 使用脚本作为参数运行 pythonw

    cd E:\my\script\folder\
    pythonw script.py
    
于 2017-02-08T08:48:32.687 回答
-1

升级到我的计算机 RAM 后,我遇到了类似的问题。结果我不得不重新安装 Pillow(用于图像处理的库)。因此,请确保已安装它,如果未安装,请使用 cmd 中的“pip install Pillow”安装它。

于 2017-07-19T19:38:10.210 回答