__main__
— Ambiente de código principal¶
Em Python, o nome especial __main__
é usado em duas construções importantes:
O nome do ambiente principal do programa, que pode ser verificado usando a expressão
__name__ == '__main__'
; eo arquivo
__main__.py
em pacotes Python.
Ambas as formas estão relacionadas aos módulos Python; como os usuários interagem com eles e como eles interagem entre si. Eles serão explicados em detalhes abaixo. Se você ainda não conhece módulos Python, veja a seção Módulos para uma introdução.
__name__ == '__main__'
¶
Quando um pacote ou módulo Python é importado, __name__
é definido como o nome do módulo. Normalmente, este é o nome do próprio arquivo Python sem a extensão .py
:
>>> import configparser
>>> configparser.__name__
'configparser'
Caso o arquivo seja parte de um pacote, __name__
também incluirá o nome da pasta raiz do pacote.
>>> from concurrent.futures import process
>>> process.__name__
'concurrent.futures.process'
Porém, se o módulo for executado como o código principal, __name__
passa a ser definido como a string '__main__'
O que é o “ambiente de código principal”?¶
__main__
é o nome do ambiente principal no qual o código é executado. “Ambiente de código principal” é o primeiro módulo Python definido pelo usuário que começa a ser executado. É considerado principal porque ele importa todos os outros módulos que o programa precisa. As vezes, “ambiente principal” também pode ser chamado de “ponto de entrada” da aplicação.
O ambiente de código principal pode ser:
o escopo de um prompt de comando interativo:
>>> __name__ '__main__'
o módulo Python passado ao interpretador do Python como um argumento correspondente ao nome do arquivo:
$ python3 helloworld.py Hello, world!
o módulo ou pacote Python passado ao interpretador do Python com o argumento
-m
:$ python3 -m tarfile usage: tarfile.py [-h] [-v] (...)
código Python lido pelo interpretador através da entrada padrão de linha de comando:
$ echo "import this" | python3 The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. ...
código Python passado ao interpretador do Python com o argumento
-c
:$ python3 -c "import this" The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. ...
Em cada uma destas situações, a variável especial __name__
passa a ser definida como '__main__'
.
Como resultado, um módulo pode saber se está ou não sendo executado no ambiente principal verificando seu próprio __name__
, que habilita um termo comum para executar código condicionalmente quando o módulo não é inicializado a partir de uma instrução de importação:
if __name__ == '__main__':
# Execute when the module is not initialized from an import statement.
...
Ver também
Para uma visão mais detalhada sobre como __name__
é definido em todas as situações, veja a sessão Módulos.
Uso idiomático¶
Alguns módulos contém códigos que são específicos para serem usados como scripts, como análise de argumentos através de linha de comando ou leitura de dados da entrada padrão. Se um módulo como o citado for importado em um outro módulo diferente, por exemplo em testes unitários, o código do script também seria executado de forma indesejada.
É aqui onde o uso do trecho de código if __name__ == '__main__'
revela-se útil. Os códigos dentro desta condicional não rodarão ao não ser que o módulo seja executado através do ambiente principal.
Colocar o mínimo de instruções possível no bloco abaixo de if __name__ == '__main__'
pode melhorar a clareza e a precisão do código. Na maioria das vezes, uma função chamada de main
encapsula o comportamento principal do programa:
# echo.py
import shlex
import sys
def echo(phrase: str) -> None:
"""A dummy wrapper around print."""
# for demonstration purposes, you can imagine that there is some
# valuable and reusable logic inside this function
print(phrase)
def main() -> int:
"""Echo the input arguments to standard output"""
phrase = shlex.join(sys.argv)
echo(phrase)
return 0
if __name__ == '__main__':
sys.exit(main()) # next section explains the use of sys.exit
Repare quem se o módulo, ao invés de ter encapsulado o código dentro da função main
, fosse colocado direto dentro do bloco if __name__ == '__main__'
, a variável phrase
seria global para todo o módulo. Isto é suscetível à erros pois outras funções dentro do módulo poderiam inadvertidamente usar a variável global ao invés da local. A função main
resolve este problema.
O uso da função main
tem o benefício adicional de a própria função echo
ser isolada e importável em outro lugar. Quando echo.py
é importado, as funções echo
e main
serão definidas, mas nenhuma delas será chamada por conta do bloco __name__ != '__main__'
.
Considerações sobre pacotes¶
main
são funções frequentemente usadas para criar ferramentas de linha de comando especificando-as como pontos de entrada para scripts de console. Quando isto é feito, pip insere a chamada da função em um modelo de script, onde o valor de retorno de main
é passado para sys.exit()
. Por exemplo:
sys.exit(main())
Uma vez que a chamada à main
está embutida dentro de sys.exit()
, a expectativa é que a sua função retorne somente valores aceitável para sys.exit()
; normalmente um inteiro ou None
(retornado de forma implícita, caso a sua função não tenha uma instrução de retorno).
Seguindo proativamente essa convenção, nosso módulo terá o mesmo comportamento quando executado diretamente (ou seja, python3 echo.py
) como terá também se posteriormente criarmos um pacote como um ponto de entrada de script de console em um pacote instalável via pip.
Em particular, tenha cuidado ao retornar strings de sua função main
. sys.exit()
interpretará um argumento de string como uma mensagem de falha, então seu programa terá um código de saída 1
, indicando falha, e a string será escrita em sys.stderr
. O exemplo anterior de echo.py
exemplifica o uso da convenção sys.exit(main())
.
Ver também
O Guia de Usuário para Empacotamento de Python contém uma coleção de tutoriais e referências sobre como distribuir e instalar pacotes Python com ferramentas modernas.
__main__.py
em pacotes Python¶
Se você não estiver familiarizado com pacotes Python, veja a seção Pacotes do tutorial. Mais comumente, o arquivo __main__.py
é usado para fornecer uma interface de linha de comando para um pacote. Considere o seguinte pacote hipotético, “bandclass”:
bandclass
├── __init__.py
├── __main__.py
└── student.py
__main__.py
será executado quando o próprio pacote for invocado diretamente da linha de comando usando o sinalizador -m
. Por exemplo:
$ python3 -m bandclass
Este comando fará com que __main__.py
seja executado. Como você utiliza esse mecanismo dependerá da natureza do pacote que você está escrevendo, mas neste caso hipotético, pode fazer sentido permitir que o professor procure alunos:
# bandclass/__main__.py
import sys
from .student import search_students
student_name = sys.argv[1] if len(sys.argv) >= 2 else ''
print(f'Found student: {search_students(student_name)}')
Observe que from .student import search_students
é um exemplo de importação relativa. Esse estilo de importação pode ser usado ao fazer referência a módulos em um pacote. Para mais detalhes, veja Referências em um mesmo pacote na seção Módulos do tutorial.
Uso idiomático¶
O conteúdo do __main__.py
normalmente não é protegido por um bloco if __name__ == '__main__'
. Em vez disso, esses arquivos são mantidos curtos e importa funções para serem executados a partir de outros módulos. Esses outros módulos podem então ter suas unidades facilmente testadas e são adequadamente reutilizáveis.
Se usado, o bloco condicional if __name__ == '__main__'
ainda funcionará como esperado para o arquivo __main__.py
dentro de um pacote, pois seu atributo __name__
incluirá o caminho do pacote se importado:
>>> import asyncio.__main__
>>> asyncio.__main__.__name__
'asyncio.__main__'
Isso não funcionará para arquivos __main__.py
no diretório raiz de um arquivo .zip. Portanto, para consistência, dê preferência para __main__.py
minimalistas, como o venv
mencionado abaixo.
Ver também
Veja venv
, da biblioteca padrão, para um exemplo de pacote com um __main__.py
minimalista. Ele não contém um bloco if __name__ == '__main__'
. Você pode invocá-lo com python -m venv [directory]
.
Veja runpy
para mais detalhes sobre o sinalizador -m
para o executável do interpretador.
Veja zipapp
para saber como executar aplicativos compactados como arquivos .zip. Nesse caso, o Python procura um arquivo __main__.py
no diretório raiz do arquivo.
import __main__
¶
Independentemente do módulo com o qual um programa Python foi iniciado, outros módulos executados no mesmo programa podem importar o escopo do ambiente principal (espaço de nomes) importando o módulo __main__
. Isso não faz a importação de um arquivo __main__.py
, mas sim qualquer módulo que recebeu o nome especial '__main__'
.
Aqui está um módulo de exemplo que consome o espaço de nomes __main__
:
# namely.py
import __main__
def did_user_define_their_name():
return 'my_name' in dir(__main__)
def print_user_name():
if not did_user_define_their_name():
raise ValueError('Define the variable `my_name`!')
if '__file__' in dir(__main__):
print(__main__.my_name, "found in file", __main__.__file__)
else:
print(__main__.my_name)
Exemplo de uso deste módulo pode ser como abaixo:
# start.py
import sys
from namely import print_user_name
# my_name = "Dinsdale"
def main():
try:
print_user_name()
except ValueError as ve:
return str(ve)
if __name__ == "__main__":
sys.exit(main())
Agora, se iniciarmos nosso programa, o resultado seria assim:
$ python3 start.py
Define the variable `my_name`!
O código de saída do programa seria 1, indicando um erro. Descomentar a linha com my_name = "Dinsdale"
corrige o programa e agora ele sai com o código de status 0, indicando sucesso:
$ python3 start.py
Dinsdale found in file /path/to/start.py
Observe que a importação de __main__
não causa nenhum problema com a execução involuntária de código principal destinado ao uso de script que é colocado no bloco if __name__ == "__main__"
do módulo start
. Por que isso funciona?
O Python insere um módulo __main__
vazio em sys.modules
na inicialização do interpretador e o preenche executando o código principal. Em nosso exemplo, este é o módulo start
que executa linha por linha e importa namely
. Por sua vez, namely
importa __main__
(que é realmente start
). Isso é um ciclo de importação! Felizmente, como o módulo __main__
parcialmente preenchido está presente em sys.modules
, o Python o passa para namely
. Veja Considerações especiais sobre __main__ na referência do sistema de importação para detalhes sobre como isso funciona.
O REPL do Python é outro exemplo de um “ambiente principal”, então qualquer coisa definida no REPL se torna parte do escopo do __main__
:
>>> import namely
>>> namely.did_user_define_their_name()
False
>>> namely.print_user_name()
Traceback (most recent call last):
...
ValueError: Define the variable `my_name`!
>>> my_name = 'Jabberwocky'
>>> namely.did_user_define_their_name()
True
>>> namely.print_user_name()
Jabberwocky
Note que neste caso o escopo __main__
não contém um atributo __file__
, pois é interativo.
O escopo __main__
é usado na implementação de pdb
e rlcompleter
.