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. немає критики ОП , хто не міг знати заздалегідь, але тим не менше він заражає значення цього питання , як в йти до ресурсу про Пітоні ш .
mnagel

Відповіді:


170

Якщо ви не хочете, щоб під час запуску програми з'явилося вікно терміналу, використовуйте pythonw.exe;
В іншому випадку використовуйтеpython.exe

Щодо помилки синтаксису: print тепер це функція в 3.x,
тому використовуйте замість цього:

print("a")

283

Для узагальнення та доповнення існуючих відповідей:

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

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

      • Якщо було створено нове вікно консолі, воно залишається відкритим, поки сценарій не припиниться.
      • При виклику з наявного вікна консолі запит блокується, поки сценарій не припиняється.
  • pythonw.exeце програма GUI для запуску сценаріїв GUI / no-UI-at-all .

    • НЕ відкриється вікно консолі .
    • Виконання є асинхронне :
      • При виклику з вікна консолі сценарій просто запускається, і підказка повертається відразу ж, сценарій все ще запущений чи ні.
    • Стандартні потоки 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сценарії безпосередньо ( на відміну від проходження шляху файлу сценарію до 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на ній, то у вас буде заплутана безладність обох процесів, що гоняться одночасно до консолі.
Ерік Нд

2
Процес користувальницького режиму створюється системним викликом NtCreateUserProcess. Якщо виконується цільова програма - це консольна програма, система безумовно успадковує стандартні ручки батьків. Але для програми без консолі потрібно чітко сказати, щоб вона успадкувала батьківські спадкові ручки. Щоб запустити файл на основі асоціації файлів, виклику cmd ShellExecuteEx, який не успадковує явно оброблювані дані при виклику CreateProcess=> NtCreateUserProcess. Отже, перенаправлення стандартного вводу / виводу працює в cmd при запуску консольних .py-скриптів, але не неконсольних .pyw-скриптів.
Ерік Нд

2
ЦМД оболонка спочатку намагається CreateProcessз bInheritHandlesпередається як TRUE. Він повертається лише ShellExecuteExтоді, коли CreateProcessне вдається, тому що ціль не є виконуваним PE (наприклад, це .py-скрипт) або вимагає підвищення (наприклад, osk.exe). Тому , коли ви безпосередньо працювати pythonw.exeабо pyw.exeвін буде наслідувати CMD - х StandardInput, StandardOutputі StandardError, що CMD ( на насправді ЕПТ) модифікує через SetStdHandleдо і після виклику , CreateProcessколи стандартне введення / виведення перенаправляється на труби, файл або пристрій.
Ерік Вс

2
Зауважте, що cmd не використовує STARTUPINFOручки (hStdInput, hStdOutput, hStdErr), на відміну від Python's subprocess.Popen. Це може відійти від цього, оскільки це однопоточна програма. Тільки завдяки цій конструкції перенаправлення працює взагалі ShellExecuteEx(лише для консольних програм, як зазначалося), оскільки інтерфейс API оболонки GUI в іншому випадку не підтримує стандартні введення / виведення.
Ерік Вс


16

Якщо ви збираєтесь викликати скрипт python з якогось іншого процесу (скажімо, з командного рядка), використовуйте pythonw.exe. В іншому випадку ваш користувач буде постійно бачити cmdвікно, запускаючи процес python. Він все одно запустить ваш сценарій так само, але він не буде втручатися у користувацький досвід.

Прикладом може бути надсилання електронного листа; python.exeз'явиться вікно CLI, надішле електронний лист, а потім закриє вікно. Це з’явиться як швидкий спалах, і його можна вважати дещо дратівливим. pythonw.exeуникає цього, але все ж надсилає електронний лист.


6
Правда, але знову «скажімо, з командного рядка»: Якщо ви вже перебуваєте в (термінал) вікна консолі, то python.exeбуде НЕ відкрити ще один.
mklement0

2

Я намагався змусити це працювати деякий час. Як тільки ви зміните розширення на .pyw, переконайтеся, що ви відкриєте властивості файлу та направляєте шлях "відкрити" до pythonw.exe.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.