Por que __name__ == “__main__” ?

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)
Agora, o comportamento do programa será diferente quando executado pela linha de comando (quando o __name__ for igual a string “__main__”), do que quando for importado como módulo.

16 comentários sobre “Por que __name__ == “__main__” ?

  1. Pingback: Dúvidas mais comum do python » Naison Souza
  2. Pingback: Arroche o nó [Python] | Programação. IA e mais.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s