pythonw.exe ou python.exe?

157

Para encurtar a história: pythonw.exenão faz nada, python.exenão aceita nada (qual devo usar?)

test.py:

print "a"

Janela 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, diga-me o que estou fazendo de errado.

não funciona
fonte
14
infelizmente, isso mistura os dois aspectos python x pythonw (geralmente o aspecto mais interessante) e algumas sintaxes básicas mudam de python2 para python3. nenhuma crítica do OP que não poderia saber de antemão, mas mesmo assim ele contamina o valor desta questão como o go-to de recursos sobre python w .
23417 mnagel

Respostas:

170

Se você não deseja que uma janela do terminal seja exibida quando você executa o programa, use pythonw.exe;
Caso contrário, usepython.exe

Com relação ao erro de sintaxe: print agora é uma função no 3.x
Então, use:

print("a")
carne_mecânica
fonte
283

Para resumir e complementar as respostas existentes:

  • python.exeé um aplicativo de console (terminal) para ativar scripts do tipo CLI .

    • A menos que seja executado a partir de uma janela de console existente, python.exe abre uma nova janela de console .
    • Padrão córregos sys.stdin , sys.stdoute sys.stderrestá ligado à janela do console .
    • A execução é síncrona quando iniciada a partir de uma cmd.exejanela do console ou do PowerShell: Veja o primeiro comentário de eryksun abaixo.

      • Se uma nova janela do console foi criada, ela permanece aberta até o script terminar.
      • Quando chamado a partir de uma janela do console existente, o prompt é bloqueado até o script terminar.
  • pythonw.exeé um aplicativo GUI para iniciar scripts GUI / no-UI-at-all .

    • Nenhuma janela do console é aberta.
    • A execução é assíncrona :
      • Quando chamado a partir de uma janela do console, o script é simplesmente iniciado e o prompt retorna imediatamente, independentemente de o script ainda estar em execução ou não.
    • Padrão córregos sys.stdin , sys.stdoute sys.stderrsão não disponível .
      • Cuidado : A menos que você tome medidas extras , isso pode causar efeitos colaterais inesperados :
        • Exceções não tratadas fazem com que o script seja interrompido silenciosamente .
        • No Python 2.x, simplesmente tentar usar print()pode fazer com que isso aconteça (no 3.x, print()simplesmente não tem efeito).
        • Para impedir isso dentro do seu script e para saber mais, veja esta resposta minha.
        • Ad-hoc , você pode usar o redirecionamento de saída : Obrigado, @handle.
          pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt
          (do PowerShell:)
          cmd /c pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txtpara capturar a saída stdout e stderr nos arquivos .
          Se você está confiante de que o uso de print()é o único motivo pelo qual seu script falha silenciosamente pythonw.exee não está interessado na saída stdout, use o comando @ handle nos comentários:
          pythonw.exe yourScript.pyw 1>NUL 2>&1
          Aviso : Esta técnica de redirecionamento de saída não funciona ao chamar *.pywscripts diretamente ( em vez de passar o caminho do arquivo de script para pythonw.exe). Veja o segundo comentário de eryksun e seus follow-ups abaixo.

Você pode controlar qual dos executáveis ​​executa seu script por padrão - como quando aberto no Explorer - escolhendo a extensão de nome de arquivo correta :

  • *.py por padrão, os arquivos são associados (chamados) a python.exe
  • *.pyw por padrão, os arquivos são associados (chamados) a pythonw.exe
mklement0
fonte
1
PS: Funciona quando eu canalizo stdout e stderr em algum lugar: > pythonw ls.pyw >nul 2>&1(mesmo que nada esteja escrito).
manipula
1
Esse comportamento síncrono e assíncrono é apenas do prompt de comando interativo cmd.exe sem usar o startcomando Na verdade, ele inspeciona o PEBprocesso filho para determinar se é um processo do console. O processo de host do console (conhost.exe) não se importa com isso. Se você costuma subprocess.Popenanexar outra python.exeinstância ao console atual e não o waitfaz, terá uma confusão confusa dos dois processos correndo para acessar o console simultaneamente.
Eryk Sun
2
Um processo no modo de usuário é criado pela chamada do sistema NtCreateUserProcess. Se o executável de destino for um programa de console, o sistema herda incondicionalmente os identificadores padrão do pai. Mas para um programa que não seja do console, é necessário que seja explicitamente instruído a herdar os identificadores herdáveis ​​do pai. Para executar um arquivo com base em uma associação de arquivos, o cmd chama ShellExecuteEx, que não herda explicitamente os identificadores quando chama CreateProcess=> NtCreateUserProcess. Consequentemente, o redirecionamento de E / S padrão funciona em cmd ao iniciar scripts .py do console, mas não scripts .pyw que não são do console.
Eryk Sun
2
O shell do cmd tenta primeiro CreateProcesscom bInheritHandlespassou como TRUE. Ele só retorna ShellExecuteExquando CreateProcessfalha porque o destino não é um executável do PE (por exemplo, é um script .py) ou requer elevação (por exemplo, osk.exe). Portanto, quando você executa diretamente pythonw.exeou pyw.exe, ele herdará os cmd's StandardInput, StandardOutpute StandardError, qual cmd (na verdade o CRT) modifica via SetStdHandleantes e depois da chamada CreateProcessquando a E / S padrão é redirecionada para um canal, arquivo ou dispositivo.
Eryk Sun
2
Observe que o cmd não usa as STARTUPINFOalças (hStdInput, hStdOutput, hStdErr), ao contrário do Python subprocess.Popen. Ele pode se safar disso porque é um programa de thread único. É somente devido a esse design que o redirecionamento funciona ShellExecuteEx(apenas para programas de console, conforme observado), porque a API do shell da GUI não tem suporte para E / S padrão.
Eryk Sun
16

Se você quiser chamar um script python de outro processo (por exemplo, na linha de comando), use pythonw.exe. Caso contrário, seu usuário verá continuamente uma cmdjanela iniciando o processo python. Ele ainda executará seu script da mesma forma, mas não interferirá na experiência do usuário.

Um exemplo pode estar enviando um email; python.exeirá aparecer uma janela da CLI, enviar o email e fechar a janela. Aparecerá como um flash rápido e pode ser considerado um pouco irritante. pythonw.exeevita isso, mas ainda envia o email.

Droogans
fonte
6
"Digamos, na linha de comando" É verdade, mas re: Se você já está em uma janela do console (terminal), então python.exeserá não abrir outra.
mklement0
2

Eu estava lutando para fazer isso funcionar por um tempo. Depois de alterar a extensão para .pyw, abra as propriedades do arquivo e direcione o caminho "abrir com" para pythonw.exe.

Ngula
fonte
-4

Na minha experiência, o pythonw.exe é mais rápido, pelo menos, com o uso de pygame.

Lenart Svetek
fonte