【问题标题】:pythonw.exe or python.exe?pythonw.exe 还是 python.exe?
【发布时间】:2012-03-31 03:35:16
【问题描述】:

长话短说:pythonw.exe 什么都不做,python.exe 什么都不接受(我应该使用哪一个?)

test.py:

print "a"

CMD 窗口:

C:\path>pythonw.exe test.py
<BLANK LINE>
C:\path>

C:\path>python.exe test.py
  File "C:\path\test.py", line 7
    print "a"
            ^
SyntaxError: invalid syntax

C:\path>

请告诉我我做错了什么。

【问题讨论】:

  • 不幸的是,这混合了 python 与 pythonw 两个方面(通常是更有趣的方面)以及从 python2 到 python3 的一些基本语法变化。没有批评事先无法知道的 OP,但是它玷污了这个问题作为关于 pythonw 首选资源的价值。

标签: python python-3.x


【解决方案1】:

总结和补充现有答案:

  • python.exe 是一个控制台(终端)应用程序用于启动 CLI 类型的脚本(控制台应用程序)

    • 除非从现有的控制台窗口运行,python.exe 打开一个新的控制台窗口

    • 标准流sys.stdinsys.stdoutsys.stderr连接到控制台窗口

    • cmd.exe 或 PowerShell 控制台窗口启动时,执行是同步请参阅下面eryksun 的第一条评论。

      • 如果创建了新的控制台窗口,它将保持打开状态,直到脚本终止。
      • 从现有控制台窗口调用时,提示将被阻止,直到脚本终止。
  • pythonw.exe 是一个 GUI 应用程序用于启动 GUI/no-UI-at-all 脚本

    • 没有打开任何控制台窗口
    • 执行是异步
      • 当从控制台窗口调用时,脚本只是启动,无论脚本是否仍在运行,都会立即返回提示。
    • 标准流sys.stdinsys.stdoutsys.stderr不可用
      • 注意除非您采取额外措施,否则会有可能出现意想不到的副作用
        • 未处理的异常导致脚本中止静默
        • 在 Python 2.x 中,简单地尝试使用 print() 会导致这种情况发生(在 3.x 中,print() 根本没有效果)。
          • 在您的脚本中防止这种情况发生,并了解更多信息,请参阅我的 this answer
          • Ad-hoc,您可以使用输出重定向谢谢@handle。
            pythonw.exe yourScript.pyw 1&gt;stdout.txt 2&gt;stderr.txt
            (来自 PowerShell:
            cmd /c pythonw.exe yourScript.pyw 1&gt;stdout.txt 2&gt;stderr.txt)在文件中捕获标准输出和标准错误输出。
            如果您确信使用print() 是您的脚本以pythonw.exe 静默失败的唯一原因,并且您对stdout 输出不感兴趣,请使用cmets 中的@handle 命令:
            pythonw.exe yourScript.pyw 1&gt;NUL 2&gt;&amp;1
            警告:当调用*.pyw 脚本直接(而不是将脚本文件路径传递给@ 987654345@)。 请参阅eryksun 的第二条评论及其下面的后续内容。

您可以控制哪些可执行文件默认运行您的脚本 - 例如从资源管理器打开时 - 通过选择正确的文件扩展名

  • *.py 文件默认与python.exe 关联(调用)
  • *.pyw 文件默认与pythonw.exe 关联(调用)

【讨论】:

  • PS:当我在某处管道 stdout 和 stderr 时它确实有效:&gt; pythonw ls.pyw &gt;nul 2&gt;&amp;1(即使没有写入任何内容)。
  • 这种同步和异步行为只是来自 cmd.exe 交互式命令提示符,没有使用start 命令。它实际上检查子进程的PEB 以确定它是否是控制台进程。控制台主机进程(conhost.exe)不关心这个。如果您使用subprocess.Popen 将另一个python.exe 实例附加到当前控制台,而不是wait,那么您将有两个进程争相同时访问控制台的混乱混乱。
  • 一个用户模式进程由系统调用NtCreateUserProcess创建。如果目标可执行文件是控制台程序,则系统无条件继承父级的标准句柄。但是对于非控制台程序,它需要被明确告知要继承父级的可继承句柄。要基于文件关联运行文件,cmd 调用ShellExecuteEx,它在调用CreateProcess => NtCreateUserProcess 时不会显式继承句柄。因此,在启动控制台 .py 脚本而不是非控制台 .pyw 脚本时,重定向标准 I/O 在 cmd 中有效。
  • cmd shell 首先尝试CreateProcessbInheritHandles 作为TRUE 传递。它仅在 CreateProcess 失败时退回到 ShellExecuteEx,因为目标不是 PE 可执行文件(例如,它是 .py 脚本)或需要提升(例如 osk.exe)。所以当你直接运行pythonw.exepyw.exe时,会继承cmd的StandardInputStandardOutputStandardError,这几个cmd(其实就是CRT)在调用CreateProcess前后通过SetStdHandle修改标准 I/O 被重定向到管道、文件或设备。
  • 请注意,与 Python 的 subprocess.Popen 不同,cmd 不使用 STARTUPINFO 句柄(hStdInput、hStdOutput、hStdErr)。它可以解决这个问题,因为它是一个单线程程序。只是由于这种设计,重定向完全适用于 ShellExecuteEx(仅适用于控制台程序,如前所述),因为 GUI shell API 不支持标准 I/O。
【解决方案2】:

如果您不想在运行程序时弹出终端窗口,请使用pythonw.exe
否则,使用python.exe

关于语法错误:printis now a function in 3.x
所以改用:

print("a")

【讨论】:

  • 从 Notepad++ 运行 .pyw 文件我仍然得到一个控制台窗口。为了防止这种情况,我必须双击文件名来打开应用程序。只有这样我才能看到 GUI 而没有控制台。
【解决方案3】:

根据我的经验,pythonw.exe 至少在使用 pygame 时会更快。

【讨论】:

    【解决方案4】:

    我一直在努力让它工作一段时间。将扩展名更改为 .pyw 后,请确保打开文件的属性并将“打开方式”路径指向 pythonw.exe。

    【讨论】:

      【解决方案5】:

      如果您要从其他进程(例如,从命令行)调用 python 脚本,请使用pythonw.exe。否则,您的用户将不断看到启动 python 进程的cmd 窗口。它仍然会以同样的方式运行您的脚本,但不会影响用户体验。

      一个例子可能是发送电子邮件; python.exe 将弹出一个 CLI 窗口,发送电子邮件,然后关闭窗口。它会显示为快速闪光,并且可以认为有些烦人。 pythonw.exe 避免了这种情况,但仍然发送电子邮件。

      【讨论】:

      • 是的,但是“比如说,从命令行”:如果您已经在控制台(终端)窗口中,那么python.exe不会 打开另一个。
      【解决方案6】:

      请看这里:http://docs.python.org/using/windows.html

      pythonw.exe "这会在启动时抑制终端窗口。"

      【讨论】:

      • pythonw.exe 有副作用,如果您的程序写入 stdout/stderr 流,它可能会静默失败 - 请参阅 bugs.python.org/issue706263
      猜你喜欢
      • 1970-01-01
      • 2012-04-16
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多