A linha mais estranha do Python — desmistificada
Abra quase qualquer arquivo Python e você vai ver isso eventualmente no fundo:
if __name__ == "__main__":
main()
Parece boilerplate mágico. Na verdade é uma feature muito prática uma vez que você sabe o que faz — e existe porque o Python não traça linha entre "scripts" e "bibliotecas".
O cenário: duas formas de usar um arquivo
Todo arquivo .py em Python pode ser usado de duas maneiras diferentes:
- Como script — você roda diretamente com
python3 file.py. - Como módulo — outro arquivo importa com
import file.
A linguagem não te faz declarar qual você está escrevendo. Qualquer arquivo pode acabar fazendo os dois.
Considere um arquivo chamado math_helpers.py:
# math_helpers.py
def mean(values):
return sum(values) / len(values)
def median(values):
s = sorted(values)
mid = len(s) // 2
if len(s) % 2 == 0:
return (s[mid - 1] + s[mid]) / 2
return s[mid]
# Quick smoke test while developing
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))
Se você roda esse arquivo diretamente, imprime a saída de teste — ótimo. Mas se algum outro arquivo faz import math_helpers, esses print rodam durante o import. Todo usuário do módulo vê sua saída de teste de desenvolvimento. Não ótimo.
O que __name__ é
Todo módulo Python tem uma variável embutida chamada __name__. O Python define automaticamente:
- Quando o arquivo é importado,
__name__é definido como o nome de import do módulo —"math_helpers"no exemplo acima. - Quando o arquivo é executado diretamente, o Python define
__name__como a string especial"__main__".
Isso te dá um jeito de dizer em qual modo você está. Envolva o código "só para script" num check:
# math_helpers.py
def mean(values):
return sum(values) / len(values)
def median(values):
s = sorted(values)
mid = len(s) // 2
if len(s) % 2 == 0:
return (s[mid - 1] + s[mid]) / 2
return s[mid]
if __name__ == "__main__":
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print("mean:", mean(numbers))
print("median:", median(numbers))
Agora python3 math_helpers.py imprime a saída de teste. Mas import math_helpers de outro arquivo pula o bloco inteiro — as funções estão disponíveis e nada indesejado roda.
O companheiro comum: uma função main()
A maioria dos scripts reais cresce uma função dedicada main() e mantém o bloco do guard minúsculo:
# process_orders.py
import sys
def load_orders(path):
with open(path) as f:
return [line.strip() for line in f if line.strip()]
def process(orders):
for order in orders:
print(f"Processing {order}")
def main():
if len(sys.argv) < 2:
print("Usage: python3 process_orders.py <file>")
sys.exit(1)
orders = load_orders(sys.argv[1])
process(orders)
if __name__ == "__main__":
main()
Por que se dar ao trabalho com uma main() em vez de colocar a lógica direto sob o guard?
- Testabilidade. Você pode importar o módulo e chamar
main()(ou qualquer dos helpers) de testes. - Variáveis locais. Qualquer coisa definida dentro de
main()é variável local, não um nome de nível de módulo. Isso evita colisões acidentais de nome e torna a superfície pública do módulo mais limpa. - Legibilidade. O bloco do guard agora tem duas linhas — um "entry point de script" claro em vez de uma pilha de lógica.
Uma demonstração rápida
Você pode ver o comportamento diretamente:
Quando você roda o snippet acima com Python, ele imprime __name__ is: __main__ e "being run as a script." Se algum outro arquivo importasse este, o mesmo check imprimiria o outro ramo.
Quando você não precisa do guard
Muitos arquivos Python nunca crescem um. Scripts curtos que ninguém ia importar estão bem sem:
# one_off_rename.py
import os
for name in os.listdir("."):
if name.endswith(".txt"):
os.rename(name, name.lower())
Isso está perfeitamente bem. Você não está construindo biblioteca; ninguém vai importar isto. No momento em que há lógica reutilizável num arquivo, porém — e você quer manter código com efeito colateral junto — recorra ao guard.
Entry points para pacotes instalados
Uma vez que você publica seu código como um pacote real, há um mecanismo mais formal: entry_points nos metadados do pacote, que mapeiam um comando a uma função. Usuários que instalam seu pacote recebem um comando de shell que chama a função diretamente. Mas para scripts rodando de uma pasta na sua própria máquina, o guard __main__ é a ferramenta padrão.
Fechando este capítulo
Você agora tem:
- Funções para nomear sua lógica.
*args/**kwargspara chamadas flexíveis.- Lambdas para funções descartáveis.
- Decoradores e type hints para envolver e documentar essas funções.
- Módulos, pip e ambientes virtuais para dividir código entre arquivos e projetos.
- O guard
__main__para deixar scripts e módulos coexistirem.
Próxima: classes
Você esteve emparelhando funções com dados simples — dicts, listas, tuplas. O próximo capítulo apresenta classes, o jeito do Python de amarrar dados e comportamento, e o lugar onde conceitos como self, __init__, herança e dataclasses moram.
Perguntas frequentes
O que if __name__ == '__main__' faz?
if __name__ == '__main__' faz?Só roda o bloco abaixo quando o arquivo é executado diretamente (não quando o arquivo é importado como módulo). Isso permite escrever um arquivo .py que pode ser executado como script ou importado pelas funções e classes — sem as ações de script acontecerem durante o import.
O Python precisa de uma função main?
Não. Arquivos Python rodam de cima para baixo automaticamente. Mas assim que um arquivo tem lógica que você também quer que seja importável, o guard if __name__ == '__main__' fica importante — e colocar o trabalho de topo do script dentro de uma função main() é um hábito companheiro comum.
Qual a diferença entre __name__ e __main__?
__name__ e __main__?__name__ é uma variável especial que o Python define em todo módulo. Se o arquivo é importado, __name__ é o nome do módulo (como 'util'). Se o arquivo é executado diretamente, o Python define __name__ como a string '__main__'. O check if compara os dois.