pythonw.exe还是python.exe?


157

长话短说: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>

请告诉我我在做错什么。


14
不幸的是,这混合了python vs pythonw两个方面(通常是更有趣的方面)以及从python2到python3的一些基本语法更改。没有OP的批评,谁也不能事先知道,但尽管如此它玷污这个问题进行的值去到资源有关Python w ^
mnagel '17

Answers:



283

总结和补充现有的答案:

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

    • 除非从现有控制台窗口运行,否则python.exe 将打开一个新的控制台窗口
    • 标准流 sys.stdinsys.stdout并且sys.stderr连接到控制台窗口
    • 从或PowerShell控制台窗口启动时,执行是同步的cmd.exe请参阅下面的eryksun的第一条评论。

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

    • 没有打开控制台窗口
    • 执行是异步的
      • 从控制台窗口中调用时,无论脚本是否仍在运行,仅启动脚本并立即返回提示。
    • 标准流 sys.stdinsys.stdout并且sys.stderr不可用
      • 警告除非您采取额外的步骤否则可能会带来意想不到的副作用
        • 未处理的异常会导致脚本静默中止
        • 在Python 2.x中,仅尝试使用print()会导致这种情况发生(在3.x中,print()完全没有效果)。
        • 为了防止这种情况出现在您的脚本中,并要了解更多信息,请参阅我的答案
        • 临时的,您可以使用输出重定向谢谢,@ handle。
          pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt
          (来自PowerShell :)
          cmd /c pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt捕获文件中的 stdout和stderr输出。
          如果您确信使用的print()是你的脚本就会失败的唯一原因pythonw.exe,而你不是在标准输出输出,使用从注释兴趣@拉手的命令:
          pythonw.exe yourScript.pyw 1>NUL 2>&1
          买者:这个输出重定向技术确实调用工作时*.pyw脚本直接(而不是将脚本文件路径传递到pythonw.exe)。请参阅下面的eryksun的第二条评论及其后续意见。

通过选择正确的文件扩展名,您可以控制默认情况下哪个可执行文件运行您的脚本(例如从资源管理器打开时):

  • *.py 默认情况下,文件与以下文件关联(调用) python.exe
  • *.pyw 默认情况下,文件与以下文件关联(调用) pythonw.exe

1
PS:当我将stdout和stderr传递到某个位置时,它确实起作用:(> pythonw ls.pyw >nul 2>&1即使什么都没写)。
处理

1
这种同步和异步行为仅来自cmd.exe交互式命令提示符,而没有使用该start命令。它实际上检查PEB子进程的,以确定它是否是控制台进程。控制台主机进程(conhost.exe)对此并不关心。如果您用于subprocess.Popen将另一个python.exe实例附加到当前控制台而不wait在其上,则两个进程竞相同时访问控制台会造成混乱。
Eryk Sun

2
通过系统调用创建用户模式进程NtCreateUserProcess。如果目标可执行文件是控制台程序,则系统将无条件继承父级的标准句柄。但是对于非控制台程序,则需要明确告知它继承父级的可继承句柄。要运行基于文件关联的文件,请调用cmd ShellExecuteEx,该调用在调用CreateProcess=> 时不会显式继承句柄NtCreateUserProcess。因此,当启动控制台.py脚本时,重定向标准I / O在cmd中有效,但在非控制台.pyw脚本中则无效。
Eryk Sun

2
运行cmd shell首先尝试CreateProcessbInheritHandles作为传递TRUE。它只是倒在ShellExecuteEx的时候CreateProcess,因为目标不是一个PE可执行文件(例如,它是一个脚本的.py)或需要提升失败(如osk.exe)。因此,当您直接运行pythonw.exe或时pyw.exe,它将继承cmd的StandardInputStandardOutputStandardErrorSetStdHandle在将CreateProcess标准I / O重定向到管道,文件或设备时,在调用之前和之后,cmd(实际上是CRT)都会通过cmd进行修改。
Eryk Sun

2
请注意STARTUPINFO,与Python的不同,cmd不使用句柄(hStdInput,hStdOutput,hStdErr)subprocess.Popen。因为它是单线程程序,所以可以避免这种情况。正是由于这种设计,重定向才可以ShellExecuteEx(仅针对控制台程序使用)重定向,因为GUI Shell API否则不支持标准I / O。
Eryk Sun


16

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

例如发送电子邮件。python.exe将弹出一个CLI窗口,发送电子邮件,然后关闭该窗口。它会以快速闪烁的形式出现,并且可能会有些令人讨厌。pythonw.exe避免这种情况,但仍发送电子邮件。


6
没错,但再“说,在命令行”:如果你已经在控制台(终端)窗口,然后python.exe不会打开另一个。
mklement0

2

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.