Por que __name__ == “__main__” ?

Autor: Valdir Stumm Jr

Já viu algum programa escrito em Python, que lá pelo final tem um trecho de código parecido com o código abaixo?

1
2
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:
1
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:

1
2
3
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:

1
2
3
4
5
6
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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:

1
2
3
4
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:

1
2
3
4
5
6
7
8
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__”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.
Sobre estes anúncios

Comentários