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>

Пожалуйста, скажите мне, что я делаю ужасно неправильно.

itdoesntwork
источник
14
к сожалению, это смешивает два аспекта python против pythonw (как правило, более интересный аспект) и некоторые основные изменения синтаксиса с python2 на python3. нет критики ОП , кто не мог знать заранее, но тем не менее он заражает значение этого вопроса , как в идти к ресурсу о питоне ш .
Mnagel

Ответы:

170

Если вы не хотите, чтобы окно терминала появлялось при запуске вашей программы, используйте pythonw.exe;
В противном случае используйтеpython.exe

Что касается синтаксической ошибки: print теперь это функция в 3.x,
поэтому используйте вместо:

print("a")
mechanical_meat
источник
283

Подводя итог и дополнить существующие ответы:

  • python.exeявляется (терминал) консольное приложение для запуска сценариев CLI-типа .

    • Если не запустить из существующего окна консоли, python.exe откроется новое окно консоли .
    • Стандартные потоки sys.stdin , sys.stdoutи sys.stderrкоторые подключены к окну консоли .
    • Выполнение происходит синхронно при запуске из cmd.exeокна консоли или PowerShell: см. Первый комментарий eryksun ниже.

      • Если было создано новое окно консоли, оно остается открытым до тех пор, пока скрипт не завершится.
      • При вызове из существующего окна консоли приглашение блокируется до тех пор, пока сценарий не завершится.
  • pythonw.exeэто GUI приложение для запуска GUI / не-UI-на-всех сценариев .

    • НЕТ окно консоли не открывается.
    • Исполнение асинхронное :
      • Когда скрипт вызывается из окна консоли, он просто запускается, и приглашение сразу возвращается, независимо от того, запущен скрипт или нет.
    • Стандартные потоки sys.stdin , sys.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, и вас не интересует вывод stdout, используйте команду @ handle из комментариев:
          pythonw.exe yourScript.pyw 1>NUL 2>&1
          Caveat : Этот метод перенаправления вывода не работает при непосредственном вызове *.pywскриптов ( в отличие от передачи пути к файлу сценария ). См. 2 -й комментарий eryksun и его последующие действия ниже.pythonw.exe

Вы можете контролировать, какой из исполняемых файлов запускает ваш скрипт по умолчанию - например, при открытии из Explorer - выбрав правильное расширение имени файла :

  • *.py файлы по умолчанию связаны (вызываются) с python.exe
  • *.pyw файлы по умолчанию связаны (вызываются) с pythonw.exe
mklement0
источник
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. Следовательно, перенаправление стандартного ввода-вывода работает в cmd при запуске консольных сценариев .py, но не не-консольных .pyw.
Eryk Sun
2
ЦМД оболочка сначала пытается CreateProcessс bInheritHandlesпередается как TRUE. Он возвращается только в ShellExecuteExслучае CreateProcessсбоя, поскольку цель не является исполняемым файлом PE (например, это скрипт .py) или требует повышения прав (например, osk.exe). Поэтому , когда вы непосредственно работать pythonw.exeили pyw.exeон будет наследовать CMD - х StandardInput, StandardOutputи StandardError, что CMD ( на самом деле ЭЛТ) модифицирует через SetStdHandleдо и после вызова , CreateProcessкогда стандартный ввод / вывод перенаправляется на трубы, файл или устройство.
Eryk Sun
2
Обратите внимание, что cmd не использует STARTUPINFOдескрипторы (hStdInput, hStdOutput, hStdErr), в отличие от Python subprocess.Popen. Это может сойти с рук, потому что это однопоточная программа. Только благодаря этой конструкции перенаправление работает вообще ShellExecuteEx(только для консольных программ, как уже отмечалось), потому что API оболочки графического интерфейса в противном случае не поддерживает стандартный ввод-вывод.
Eryk Sun
19

Смотрите здесь: http://docs.python.org/using/windows.html

pythonw.exe "Это подавляет окно терминала при запуске."

джон
источник
8
pythonw.exeимеет побочные эффекты, из-за которых ваша программа может молчать, если она пишет в поток stdout / stderr - см. bugs.python.org/issue706263
Анатолий techtonik
16

Если вы собираетесь вызывать скрипт Python из какого-либо другого процесса (скажем, из командной строки), используйте pythonw.exe. В противном случае ваш пользователь будет постоянно видеть cmdокно запуска процесса python. Он по-прежнему будет запускать ваш скрипт точно так же, но он не будет влиять на пользовательский опыт.

Примером может быть отправка электронного письма; python.exeпоявится окно CLI, отправьте электронное письмо, затем закройте окно. Он будет выглядеть как быстрая вспышка, и его можно считать несколько раздражающим. pythonw.exeизбегает этого, но все равно отправляет электронное письмо.

Droogans
источник
6
Правда, но вновь «скажем, из командной строки»: Если вы уже находитесь в (терминал) окна консоли, то python.exeбудет не открыть еще один.
mklement0
2

Я изо всех сил пытался заставить это работать некоторое время. После того, как вы измените расширение на .pyw, убедитесь, что вы открыли свойства файла и направили открытый путь к pythonw.exe.

Ngula
источник
-4

По моему опыту pythonw.exe быстрее по крайней мере с использованием pygame.

Ленарт Светек
источник