O que é o __main__.py?

326

Para que serve o __main__.pyarquivo, que tipo de código devo inserir e quando devo ter um?

Monika Sulik
fonte

Respostas:

320

Geralmente, um programa Python é executado nomeando um arquivo .py na linha de comando:

$ python my_program.py

Você também pode criar um diretório ou arquivo zip cheio de código e incluir a __main__.py. Em seguida, você pode simplesmente nomear o diretório ou zipfile na linha de comando, e ele executa __main__.pyautomaticamente:

$ python my_program_dir
$ python my_program.zip
# Or, if the program is accessible as a module
$ python -m my_program

Você terá que decidir por si mesmo se seu aplicativo pode se beneficiar da execução assim.


Observe que um __main__ módulo geralmente não vem de um __main__.pyarquivo. Pode, mas geralmente não. Quando você executa um script como python my_program.py, o script será executado como o __main__módulo em vez do my_programmódulo. Isso também acontece para os módulos executados como python -m my_module, ou de várias outras maneiras.

Se você viu o nome __main__em uma mensagem de erro, isso não significa necessariamente que você deve procurar um __main__.pyarquivo.

Ned Batchelder
fonte
22
Eu achei python -m program_dire python program_dirum pouco diferente: o último nunca corre__init__.py no diretório (se houver um).
brk
5
@ brk: Esse não parece ser o caso agora. Eu apenas tentei python3 program_dire funcionou __init__.py.
Mk12 03/01/19
@ mk12 Eu apenas tentei confirmar as descobertas de @ brk: python3 dirroda, __main__.pymas não __init__.py, enquanto python3 -m dirroda ambos.
Marcello Romani
1
@ mk12 Provavelmente você tinha algum código dentro __main__.py qual desencadeou a importação de__init__.py
wim 24/04
100

Para que serve o __main__.pyarquivo?

Ao criar um módulo Python, é comum fazer com que o módulo execute alguma funcionalidade (geralmente contida em uma mainfunção) quando executado como o ponto de entrada do programa. Isso geralmente é feito com o seguinte idioma comum, localizado na parte inferior da maioria dos arquivos Python:

if __name__ == '__main__':
    # execute only if run as the entry point into the program
    main()

Você pode obter a mesma semântica para um pacote Python __main__.py. Este é um prompt do shell linux $. Se você não tiver o Bash (ou outro shell Posix) no Windows, crie esses arquivos demo/__<init/main>__.pycom o conteúdo entre EOFs:

$ mkdir demo
$ cat > demo/__init__.py << EOF
print('demo/__init__.py executed')
def main():
    print('main executed')
EOF
$ cat > demo/__main__.py << EOF
print('demo/__main__.py executed')
from __init__ import main
main()
EOF

(Em um shell Posix / Bash, você pode fazer o acima sem os se << EOFterminar EOFs digitando Ctrl+D , o caractere de fim de arquivo, no final de cada comando cat)

E agora:

$ python demo
demo/__main__.py executed
demo/__init__.py executed
main executed

Você pode derivar isso da documentação. A documentação diz:

__main__ - Ambiente de script de nível superior

'__main__'é o nome do escopo no qual o código de nível superior é executado. Um módulo __name__é definido igual a '__main__'quando lido da entrada padrão, de um script ou de um prompt interativo.

Um módulo pode descobrir se está sendo executado no escopo principal ou não, verificando seu próprio __name__ , o que permite um idioma comum para executar condicionalmente o código em um módulo quando é executado como um script ou com python -mmas não quando é importado:

if __name__ == '__main__':
      # execute only if run as a script
      main()

Para um pacote, o mesmo efeito pode ser alcançado incluindo uma __main__.py módulo, cujo conteúdo será executado quando o módulo for executado -m.

Fechado

Você também pode empacotar isso em um único arquivo e executá-lo na linha de comando, como este - mas observe que os pacotes compactados não podem executar subpacotes ou submódulos como ponto de entrada:

$ python -m zipfile -c demo.zip demo/*
$ python demo.zip
demo/__main__.py executed
demo/__init__.py executed
main() executed
Aaron Hall
fonte
31

__main__.pyé usado para programas python em arquivos zip. O __main__.pyarquivo será executado quando o arquivo zip for executado. Por exemplo, se o arquivo zip fosse o seguinte:

test.zip
     __main__.py

e o conteúdo de __main__.pyera

import sys
print "hello %s" % sys.argv[1]

Então, se fôssemos correr python test.zip world, teríamoshello world .

Portanto, o __main__.pyarquivo é executado quando o python é chamado em um arquivo zip.

Pimentas azuis
fonte
23

Você cria __main__.pyno yourpackagepara torná-lo executável como:

$ python -m yourpackage
anatoly techtonik
fonte
1
-mfunciona se apenas o programa é acessível como um módulo, então você poderia usar python <yourpackage>NOTA: sem -mopção
Benyamin Jafari
1
@BenyaminJafari não é possível escrever um programa Python em linha de comando que não esteja acessível como um módulo . Talvez você quis dizer package?
Anatoly techtonik
1
quando criamos um pacote Python que contém o arquivo .py principal , para executá-lo python -m <yourproject>não funciona, -mé uma opção redundante, mas python <yourpackage>funciona bem.
Benyamin Jafari
@BenyaminJafari O sinalizador -m faz diferença em alguns casos. Executar a partir do diretório ae assumir o script a/b/c/__main__.py... python -m b.cserá executado a partir do diretório ae as importações do script principal serão relativas a a. Mas python b/cserá executado a partir do escopo de importação de dir ce, portanto, qualquer importação como no script principal como import b.dfalhará.
MikeCPT 18/08/19
14

Se o seu script for um diretório ou arquivo ZIP em vez de um único arquivo python, __main__.pyserá executado quando o "script" for passado como argumento para o intérprete python.

Wooble
fonte