pythonw.exe ou python.exe?

157

En bref: pythonw.exene fait rien, python.exen'accepte rien (lequel dois-je utiliser?)

test.py:

print "a"

Fenêtre 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>

S'il vous plaît dites-moi ce que je fais mal

ça ne fonctionne pas
la source
14
malheureusement, cela mêle les deux aspects python vs pythonw (généralement l'aspect le plus intéressant) et certains changements de syntaxe de base de python2 à python3. aucune critique de l'OP qui ne pouvait pas savoir à l' avance, mais néanmoins il entache la valeur de cette question la ressource go-to sur Python w .
mnagel

Réponses:

170

Si vous ne voulez pas qu'une fenêtre de terminal apparaisse lorsque vous exécutez votre programme, utilisez pythonw.exe;
Sinon, utilisezpython.exe

Concernant l'erreur de syntaxe: print est maintenant une fonction dans 3.x
donc utilisez à la place:

print("a")
viande_mécanique
la source
283

Pour résumer et compléter les réponses existantes:

  • python.exeest une application console (terminal) pour lancer des scripts de type CLI .

    • À moins d'être exécuté à partir d'une fenêtre de console existante, python.exe ouvre une nouvelle fenêtre de console .
    • Flux standard sys.stdin , sys.stdoutet sys.stderrsont connectés à la fenêtre de la console .
    • L'exécution est synchrone lorsqu'elle est lancée depuis une cmd.exefenêtre de console ou PowerShell: voir le premier commentaire d' eryksun ci-dessous.

      • Si une nouvelle fenêtre de console a été créée, elle reste ouverte jusqu'à ce que le script se termine.
      • Lorsqu'elle est appelée à partir d'une fenêtre de console existante, l'invite est bloquée jusqu'à ce que le script se termine.
  • pythonw.exeest une application GUI pour lancer des scripts GUI / no-UI-at-all .

    • AUCUNE fenêtre de console n'est ouverte.
    • L'exécution est asynchrone :
      • Lorsqu'il est appelé à partir d'une fenêtre de console, le script est simplement lancé et l'invite revient immédiatement, que le script soit toujours en cours d'exécution ou non.
    • Flux standard sys.stdin , sys.stdoutet ne sys.stderrsont PAS disponibles .
      • Attention : à moins que vous ne preniez des mesures supplémentaires , cela a des effets secondaires potentiellement inattendus :
        • Les exceptions non gérées provoquent le script à abandonner en silence .
        • Dans Python 2.x, le simple fait d'essayer d'utiliser print()peut provoquer cela (dans 3.x, cela print()n'a tout simplement aucun effet).
        • Pour éviter cela depuis votre script et pour en savoir plus, lisez ma réponse .
        • Ad-hoc , vous pouvez utiliser la redirection de sortie : Merci, @handle.
          pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt
          (à partir de PowerShell :)
          cmd /c pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txtpour capturer la sortie stdout et stderr dans des fichiers .
          Si vous êtes convaincu que l'utilisation de print()est la seule raison pour laquelle votre script échoue silencieusement pythonw.exeet que vous n'êtes pas intéressé par la sortie stdout, utilisez la commande @ handle des commentaires:
          pythonw.exe yourScript.pyw 1>NUL 2>&1
          Avertissement : Cette technique de redirection de sortie ne fonctionne pas lors de l'appel direct de*.pyw scripts ( par opposition à en passant le chemin du fichier de script à ). Voir le 2ème commentaire d' eryksun et ses suites ci-dessous.pythonw.exe

Vous pouvez contrôler lequel des exécutables exécute votre script par défaut - par exemple lorsqu'il est ouvert à partir de l'Explorateur - en choisissant la bonne extension de nom de fichier :

  • *.py les fichiers sont par défaut associés (appelés) avec python.exe
  • *.pyw les fichiers sont par défaut associés (appelés) avec pythonw.exe
mklement0
la source
1
PS: Cela fonctionne quand je pipe stdout et stderr quelque part: > pythonw ls.pyw >nul 2>&1(même si rien n'est écrit).
gérer le
1
Ce comportement synchrone et asynchrone provient uniquement de l'invite de commande interactive cmd.exe sans utiliser la startcommande. Il inspecte en fait le PEBprocessus enfant pour déterminer s'il s'agit d'un processus console. Le processus hôte de la console (conhost.exe) ne se soucie pas de cela. Si vous utilisez subprocess.Popenpour attacher une autre python.exeinstance à la console actuelle et que vous ne l'utilisez pas wait, vous aurez un désordre déroutant des deux processus en course pour accéder à la console simultanément.
Eryk Sun
2
Un processus en mode utilisateur est créé par l'appel système NtCreateUserProcess. Si l'exécutable cible est un programme console, le système hérite inconditionnellement des descripteurs standard du parent. Mais pour un programme non-console, il doit être explicitement dit d'hériter des handles héritables du parent. Pour exécuter un fichier basé sur une association de fichier, cmd appelle ShellExecuteEx, qui n'hérite pas explicitement de descripteurs lorsqu'il appelle CreateProcess=> NtCreateUserProcess. Par conséquent, la redirection des E / S standard fonctionne dans cmd lors du démarrage des scripts .py de la console mais pas des scripts .pyw non-console.
Eryk Sun
2
Le shell cmd essaie d'abord CreateProcessavec bInheritHandlespassé comme TRUE. Il ne se replie qu'en ShellExecuteExcas d' CreateProcesséchec car la cible n'est pas un exécutable PE (par exemple, c'est un script .py) ou nécessite une élévation (par exemple osk.exe). Donc , lorsque vous exécutez directement pythonw.exeou pyw.exe, il héritera de cmd StandardInput, StandardOutputet StandardErrorqui cmd ( en fait le CRT) par l' intermédiaire modifie SetStdHandleavant et après l' appel CreateProcesslorsque E / S standard est redirigé vers un tuyau, un fichier ou un périphérique.
Eryk Sun
2
Notez que cmd n'utilise pas les STARTUPINFOpoignées (hStdInput, hStdOutput, hStdErr), contrairement à Python subprocess.Popen. Il peut s'en tirer car c'est un programme à un seul thread. Ce n'est que grâce à cette conception que la redirection fonctionne du tout ShellExecuteEx(juste pour les programmes de console, comme indiqué) car l'API du shell GUI ne prend pas en charge les E / S standard.
Eryk Sun
16

Si vous allez appeler un script python à partir d'un autre processus (par exemple, à partir de la ligne de commande), utilisez pythonw.exe. Sinon, votre utilisateur verra en permanence une cmdfenêtre lançant le processus python. Il exécutera toujours votre script de la même manière, mais il n'empiétera pas sur l'expérience utilisateur.

Un exemple pourrait être l'envoi d'un e-mail; python.exefera apparaître une fenêtre CLI, enverra l'e-mail, puis fermera la fenêtre. Cela apparaîtra comme un éclair rapide et peut être considéré comme quelque peu ennuyeux. pythonw.exeévite cela, mais envoie toujours l'e-mail.

Droogans
la source
6
Certes, mais re « disons, à partir de la ligne de commande »: Si vous avez déjà êtes dans une fenêtre de la console (terminal), puis python.exesera pas ouvrir un autre.
mklement0
2

J'avais du mal à faire fonctionner cela pendant un moment. Une fois que vous avez changé l'extension en .pyw, assurez-vous que vous ouvrez les propriétés du fichier et dirigez le chemin "ouvrir avec" vers pythonw.exe.

Ngula
la source
-4

D'après mon expérience, pythonw.exe est au moins plus rapide avec l'utilisation de pygame.

Lenart Svetek
la source