Já viu algum programa escrito em Python, que lá pelo final tem um trecho de código parecido com o código abaixo?
if __name__ == "__main__":
# faça algo
Quem não conhece, deve estar se perguntando: que condição é essa? O que é __name__? O que é “__main__”?
Para entender isso, nada melhor que a prática. Faça o seguinte:
- Usando seu editor de textos favorito, crie um arquivo .py (por exemplo: teste.py);
- Dentro desse arquivo, coloque o seguinte código:
print __name__
OK, criamos um programa/módulo python chamado teste. Isso quer dizer que podemos executá-lo pela linha de comando, ou importá-lo em um shell python. Agora vamos executá-lo como um programa:
user@host:~/ $ python teste.py __main__
Repare na saída que o programa gerou: __main__. Esse é o nome interno que todo programa/módulo Python recebe quando executado como um programa pela linha de comando.
Agora, abra um shell Python no mesmo diretório onde o arquivo teste.py foi gravado e importe tal módulo:
Python 2.7.2+ (default, Oct 4 2011, 20:06:09) [GCC 4.6.1] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import teste teste >>>
Repare que agora, a variável __name__ foi impressa com um valor diferente: teste, que é o nome que demos ao nosso programa. Assim, o teste __name__ == “__main__” está verificando nada mais do que se o código do módulo está sendo executado como um programa, tendo sido chamado pela linha de comando, ou sendo importado como um módulo. Mas, pra que serve isso?
Vamos a outro exemplo. Vamos implementar um módulo com algumas funções que achamos úteis. Vamos chamar esse módulo como utilidades.py.
import sys
def erro(msg):
print "Erro:", msg
sys.exit(1)
def inc(x):
return x + 1
def dec(x):
return x - 1
def quadrado(x):
return x**2
Mas, enquanto vamos implementando, queremos fazer alguns testes para saber se o código funciona como esperamos, então complementamos o código acima com uns testes ao final:
import sys
def erro(msg):
print "Erro:", msg
sys.exit(1)
def inc(x):
return x + 1
def dec(x):
return x - 1
def quadrado(x):
return x**2
print inc(10) # deve mostrar 11
print dec(10) # deve mostrar 9
print quadrado(5) # deve mostrar 25
Perfeito, se executarmos o código acima pela linha de comando, teremos o resultado que esperamos:
user@host:~/ $ python utilidades.py 11 9 25
Até aí, tudo certo. Mas, e se precisarmos de uma dessas funções e importarmos esse módulo (utilidades) em algum outro programa ou até mesmo em um shell Python? Vamos ver:
Python 2.7.2+ (default, Oct 4 2011, 20:06:09) [GCC 4.6.1] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import utilidades 11 9 25 >>>
Opa! “Mas eu queria apenas usar as funções que o módulo utilidades disponibiliza, não ver esses números na tela!”. Pois é. O problema é que as três linhas de código que finalizam o módulo estão sendo executadas de forma incondicional, não importando se o programa estiver sendo executado pela linha de comando ou sendo importado em outro programa. Podemos resolver esse problema adicionando o teste __name__ == “__main__”:
import sys
def erro(msg):
print "Erro:", msg
sys.exit(1)
def inc(x):
return x + 1
def dec(x):
return x - 1
def quadrado(x):
return x**2
if __name__ == "__main__":
print inc(10)
print dec(10)
print quadrado(5)
20 comentários sobre “Por que __name__ == “__main__” ?”
Deixe um comentário
Você precisa fazer o login para publicar um comentário.
Excelente! o exemplo prático matou a pau a explicação, parabéns!
Parabéns!!!
Mt simples e direto ao ponto! Matou!
Excelente.
Perfeito!
Muuuito excelente! Obrigado!
Republicou isso em debugging on the table.
Ótima explicação, ajudou bastante. Obrigado.
Show \o/
Muito bom! Obrigado pela explicação, simples e direta!
Nossa, perfeito seu exemplo matando minha dúvida.
Muito obrigado.
uma bosta
Parabéns, explicação perfeita.
Agora entendi.
Muito Obrigado.
Favoritei seu blog!
Muito boa explicação, obrigado.
Po cara que legal pesquisei pra caramba agora entendi nessa sua explicação simples e direta, quem não entendeu aqui tem que ir para outra função não programação haha valeu.
Que bom que a explicação serviu bem para você. 🙂
Quanto a quem não entendeu a explicação, o melhor é persistir e procurar outros materiais com abordagens diferentes. 🙂
Obrigado!