pythonw.exe o python.exe?

157

Larga historia corta: pythonw.exeno hace nada, no python.exeacepta nada (¿cuál debo usar?)

test.py:

print "a"

Ventana 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>

Por favor dime que estoy haciendo terriblemente mal.

trabajo
fuente
14
desafortunadamente esto entremezcla los dos aspectos python vs pythonw (generalmente el aspecto más interesante) y algunos cambios básicos de sintaxis de python2 a python3. ninguna crítica al OP que no podía saber de antemano, pero sin embargo contamina el valor de esta pregunta como el recurso de referencia sobre python w .
mnagel

Respuestas:

170

Si no desea que aparezca una ventana de terminal cuando ejecute su programa, use pythonw.exe;
De lo contrario, usepython.exe

Con respecto al error de sintaxis: print ahora es una función en 3.x
Entonces use en su lugar:

print("a")
carne_mecánica
fuente
283

Para resumir y complementar las respuestas existentes:

  • python.exees una aplicación de consola (terminal) para iniciar scripts de tipo CLI .

    • A menos que se ejecute desde una ventana de consola existente, python.exe abre una nueva ventana de consola .
    • Flujos estándares sys.stdin , sys.stdouty sys.stderrse conecta a la ventana de la consola .
    • La ejecución es sincrónica cuando se inicia desde una cmd.exeventana de consola de PowerShell: consulte el primer comentario de eryksun a continuación.

      • Si se creó una nueva ventana de consola, permanece abierta hasta que finaliza el script.
      • Cuando se invoca desde una ventana de consola existente, la solicitud se bloquea hasta que finaliza el script.
  • pythonw.exees una aplicación GUI para iniciar guiones GUI / no-UI-at-all .

    • NO se abre la ventana de la consola .
    • La ejecución es asíncrona :
      • Cuando se invoca desde una ventana de consola, el script simplemente se inicia y el mensaje vuelve de inmediato, independientemente de si el script aún se está ejecutando o no.
    • Secuencias estándar sys.stdin , sys.stdouty NOsys.stderr están disponibles .
      • Precaución : a menos que tome medidas adicionales , esto tiene efectos secundarios potencialmente inesperados :
        • Las excepciones no controladas hacen que la secuencia de comandos se anule en silencio .
        • En Python 2.x, simplemente intentar usarlo print()puede hacer que eso suceda (en 3.x, print()simplemente no tiene efecto).
        • Para evitar eso dentro de su script , y para aprender más, vea esta respuesta mía.
        • Ad-hoc , puede usar la redirección de salida : Gracias, @handle.
          pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt
          (desde PowerShell:)
          cmd /c pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txtpara capturar salidas stdout y stderr en archivos .
          Si está seguro de que el uso de print()es la única razón por la que su script falla en silencio pythonw.exe, y no está interesado en la salida estándar, use el comando @ handle de los comentarios:
          pythonw.exe yourScript.pyw 1>NUL 2>&1
          Advertencia : esta técnica de redirección de salida no funciona al invocar *.pywscripts directamente ( en lugar de pasar la ruta del archivo de script a pythonw.exe). Vea el segundo comentario de eryksun y sus seguimientos a continuación.

Puede controlar cuál de los ejecutables ejecuta su script de forma predeterminada , como cuando se abre desde Explorer, eligiendo la extensión de nombre de archivo correcta :

  • *.py los archivos están asociados por defecto (invocados) con python.exe
  • *.pyw los archivos están asociados por defecto (invocados) con pythonw.exe
mklement0
fuente
1
PD: Funciona cuando canalizo stdout y stderr en alguna parte: > pythonw ls.pyw >nul 2>&1(aunque no hay nada escrito).
manejar el
1
Este comportamiento síncrono y asíncrono es solo desde el símbolo del sistema interactivo cmd.exe sin usar el startcomando. Realmente inspecciona el PEBproceso secundario para determinar si es un proceso de consola. El proceso de host de la consola (conhost.exe) no se preocupa por esto. Si usas subprocess.Popenpara adjuntar otra python.exeinstancia a la consola actual y no lo haces wait, entonces tendrás un lío confuso de ambos procesos corriendo para acceder a la consola simultáneamente.
Eryk dom
2
La llamada al sistema crea un proceso en modo usuario NtCreateUserProcess. Si el ejecutable de destino es un programa de consola, el sistema hereda incondicionalmente los identificadores estándar de los padres. Pero para un programa que no es de consola, se requiere que se le diga explícitamente que herede los identificadores heredables del padre. Para ejecutar un archivo basado en una asociación de archivos, cmd llama ShellExecuteEx, que no hereda explícitamente los identificadores cuando llama a CreateProcess=> NtCreateUserProcess. En consecuencia, la redirección de E / S estándar funciona en cmd al iniciar los scripts .py de consola, pero no los scripts .pyw que no son de consola.
Eryk dom
2
El shell cmd primero intenta CreateProcesscon bInheritHandlespasado como TRUE. Solo vuelve a funcionar ShellExecuteExcuando CreateProcessfalla porque el objetivo no es un ejecutable PE (por ejemplo, es un script .py) o requiere elevación (por ejemplo, osk.exe). Así que cuando se ejecuta directamente pythonw.exeo pyw.exe, heredará de cmd StandardInput, StandardOutputy StandardError, lo que cmd (en realidad el CRT) modifica a través de SetStdHandleantes y después de llamar CreateProcesscuando E / S estándar es redirigido a una tubería, un archivo o dispositivo.
Eryk dom
2
Tenga en cuenta que cmd no utiliza los STARTUPINFOidentificadores (hStdInput, hStdOutput, hStdErr), a diferencia de Python subprocess.Popen. Puede salirse con la suya porque es un programa de subproceso único. Es solo debido a este diseño que la redirección funciona en absoluto ShellExecuteEx(solo para los programas de consola, como se señaló) porque la API de shell GUI no tiene soporte para E / S estándar.
Eryk dom
16

Si va a llamar a un script de Python desde algún otro proceso (por ejemplo, desde la línea de comandos), use pythonw.exe. De lo contrario, su usuario verá continuamente una cmdventana que inicia el proceso de Python. Seguirá ejecutando su script de la misma manera, pero no interferirá con la experiencia del usuario.

Un ejemplo podría ser enviar un correo electrónico; python.exeaparecerá una ventana de CLI, enviará el correo electrónico y luego cerrará la ventana. Aparecerá como un flash rápido, y puede considerarse algo molesto. pythonw.exeevita esto, pero aún así envía el correo electrónico.

Droogans
fuente
66
"Por ejemplo, desde la línea de comandos" Es cierto, pero re: Si ya está en una ventana de la consola (terminal), entonces python.exeserá no abrir otra.
mklement0
2

Estaba luchando para que esto funcionara por un tiempo. Una vez que cambie la extensión a .pyw, asegúrese de abrir las propiedades del archivo y dirigir la ruta "abrir con" a pythonw.exe.

Ngula
fuente
-4

En mi experiencia, pythonw.exe es más rápido al menos con el uso de pygame.

Lenart Svetek
fuente