pythonw.exe czy python.exe?

157

Krótko mówiąc: pythonw.exenic nie robi, nic nie python.exeakceptuje (którego powinienem użyć?)

test.py:

print "a"

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

Proszę, powiedz mi, co robię strasznie źle.

itdoesntwork
źródło
14
niestety łączy to ze sobą dwa aspekty python i pythonw (ogólnie rzecz biorąc, bardziej interesujący aspekt) i niektóre podstawowe zmiany składni z python2 na python3. nie krytyka PO, którzy nie mogli wiedzieć wcześniej, niemniej jednak obarczone wartość tej kwestii, w iść do zasobu o pytona wag .
mnagel

Odpowiedzi:

170

Jeśli nie chcesz, aby okno terminala wyskakiwało po uruchomieniu programu, użyj pythonw.exe;
W przeciwnym razie użyjpython.exe

Odnośnie błędu składni: print jest teraz funkcją w 3.x,
więc użyj zamiast tego:

print("a")
mięso_mechaniczne
źródło
283

Podsumowując i uzupełniając istniejące odpowiedzi:

  • python.exeto konsola (terminal) do uruchamiania skryptów typu CLI .

    • O ile nie uruchomisz z istniejącego okna konsoli, python.exe otwiera nowe okno konsoli .
    • Standardowe strumienie sys.stdin , sys.stdouti sys.stderrpodłączone do okna konsoli .
    • Wykonywanie jest synchroniczne po uruchomieniu z cmd.exeokna konsoli lub PowerShell: Zobacz pierwszy komentarz eryksun poniżej.

      • Jeśli zostało utworzone nowe okno konsoli, pozostaje otwarte do momentu zakończenia działania skryptu.
      • Po wywołaniu z istniejącego okna konsoli monit jest blokowany do momentu zakończenia działania skryptu.
  • pythonw.exeto aplikacja GUI do uruchamiania skryptów GUI / no-UI-at-all .

    • Żadne okno konsoli nie jest otwarte.
    • Wykonywanie jest asynchroniczne :
      • Po wywołaniu z okna konsoli skrypt jest po prostu uruchamiany, a monit natychmiast wraca, niezależnie od tego, czy skrypt nadal działa, czy nie.
    • Strumieni norma sys.stdin , sys.stdouta sys.stderrto nie jest dostępna .
      • Uwaga : jeśli nie podejmiesz dodatkowych kroków , ma to potencjalnie nieoczekiwane skutki uboczne :
        • Nieobsłużone wyjątki spowodować skrypt, aby przerwać cicho .
        • W Pythonie 2.x zwykła próba użycia print()może spowodować, że tak się stanie (w 3.x print()po prostu nie ma efektu).
        • Aby temu zapobiec i dowiedzieć się więcej, zobacz moją odpowiedź .
        • Ad-hoc , możesz użyć przekierowania wyjścia : Dzięki, @handle.
          pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt
          (z PowerShell:)
          cmd /c pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txtdo przechwytywania danych wyjściowych stdout i stderr w plikach .
          Jeśli jesteś pewien, że użycie print()jest jedynym powodem, dla którego twój skrypt nie działa po cichu pythonw.exe, i nie jesteś zainteresowany wyjściem standardowym, użyj polecenia @ handle z komentarzy:
          pythonw.exe yourScript.pyw 1>NUL 2>&1
          Uwaga : Ta technika przekierowania wyjścia nie działa podczas bezpośredniego wywoływania *.pywskryptów ( w przeciwieństwie do przekazywania ścieżki do pliku skryptu do ). Zobacz drugi komentarz eryksun i jego następstwa poniżej.pythonw.exe

Możesz kontrolować, które z plików wykonywalnych domyślnie uruchamiają Twój skrypt - na przykład po otwarciu z Eksploratora - wybierając odpowiednie rozszerzenie nazwy pliku :

  • *.py pliki są domyślnie skojarzone (wywoływane) z python.exe
  • *.pyw pliki są domyślnie skojarzone (wywoływane) z pythonw.exe
mklement0
źródło
1
PS: Działa, gdy gdzieś wysyłam rury na stdout i stderr: > pythonw ls.pyw >nul 2>&1(nawet jeśli nic nie jest napisane).
uchwyt
1
To zachowanie synchroniczne i asynchroniczne pochodzi tylko z interaktywnego wiersza polecenia cmd.exe bez użycia tego startpolecenia. W rzeczywistości sprawdza PEBproces potomny, aby określić, czy jest to proces konsoli. Proces hosta konsoli (conhost.exe) nie dba o to. Jeśli użyjesz subprocess.Popendo podłączenia innej python.exeinstancji do bieżącej konsoli, a nie waitna niej, będziesz miał mylący bałagan obu procesów ścigających się, aby uzyskać dostęp do konsoli jednocześnie.
Eryk Sun
2
Proces w trybie użytkownika jest tworzony przez wywołanie systemowe NtCreateUserProcess. Jeśli docelowy plik wykonywalny jest programem konsolowym, system bezwarunkowo dziedziczy standardowe uchwyty rodzica. Ale w przypadku programu innego niż konsola wymaga to wyraźnego polecenia, aby dziedziczenie dziedziczonych uchwytów rodzica. Aby uruchomić plik w oparciu o skojarzenie plików, wywołania cmd ShellExecuteEx, które nie dziedziczą jawnie uchwytów, gdy wywołuje CreateProcess=> NtCreateUserProcess. W konsekwencji przekierowanie standardowego wejścia / wyjścia działa w cmd podczas uruchamiania skryptów .py konsoli, ale nie w skryptach .pyw innych niż konsolowe.
Eryk Sun
2
Cmd powłoki próbuje najpierw CreateProcessz bInheritHandlesprzekazywane jako TRUE. Powraca tylko w ShellExecuteExprzypadku CreateProcessniepowodzenia, ponieważ cel nie jest plikiem wykonywalnym PE (np. Jest to skrypt .py) lub wymaga podniesienia uprawnień (np. Osk.exe). Więc kiedy uruchomić bezpośrednio pythonw.exelub pyw.exebędzie dziedziczyć cmd-tych StandardInput, StandardOutputi StandardError, co cmd (rzeczywiście CRT) modyfikuje poprzez SetStdHandleprzed i po wywołaniu CreateProcessgdy standard I / O jest przekierowany do rur, pliku lub urządzenia.
Eryk Sun
2
Zauważ, że cmd nie używa STARTUPINFOuchwytów (hStdInput, hStdOutput, hStdErr), w przeciwieństwie do Pythona subprocess.Popen. Może to ujść na sucho, ponieważ jest to program jednowątkowy. Tylko z powodu tego projektu przekierowanie w ogóle działa ShellExecuteEx(tylko dla programów konsolowych, jak wspomniano), ponieważ interfejs API powłoki GUI w przeciwnym razie nie obsługuje standardowych operacji we / wy.
Eryk Sun
16

Jeśli zamierzasz wywołać skrypt Pythona z innego procesu (powiedzmy z wiersza poleceń), użyj pythonw.exe. W przeciwnym razie użytkownik będzie stale widzieć cmdokno uruchamiające proces Pythona. Nadal będzie uruchamiał twój skrypt tak samo, ale nie przeszkadza to użytkownikowi.

Przykładem może być wysłanie wiadomości e-mail; python.exewyskoczy okno CLI, wyśle ​​wiadomość e-mail, a następnie zamknie okno. Pojawi się jako szybki błysk i można go uznać za nieco denerwujący. pythonw.exeunika tego, ale nadal wysyła wiadomość e-mail.

Droogans
źródło
6
To prawda, ale re „powiedzmy, z linii poleceń”: Jeśli już w oknie konsoli (terminal), następnie python.exebędzie nie otworzy kolejną.
mklement0
2

Przez jakiś czas starałem się, aby to zadziałało. Po zmianie rozszerzenia na .pyw, upewnij się, że otworzyłeś właściwości pliku i skieruj ścieżkę „otwórz za pomocą” na pythonw.exe.

Ngula
źródło
-4

Z mojego doświadczenia wynika, że ​​pythonw.exe jest szybszy przynajmniej przy użyciu pygame.

Lenart Svetek
źródło