Python: O que significa if __name__ == '__main__'?

Python: O que significa if __name__ == '__main__'?
Python: O que significa if __name__ == __main__ #cover

Como desenvolvedor Python, é possível que você já tenha se deparado com esse trecho de código, mas você sabe o que ele significa?

Achei um programa em Python na internet com várias funções relacionadas a dados e taxas de moedas, que podem me ajudar no meu projeto pessoal de criar um conversor de moedas.

Baixei, então, o arquivo info_moedas.py, para utilizá-lo em meu projeto, especialmente uma função que pega a taxa atual de conversão entre duas moedas (get_taxa_conversao()). O arquivo principal do meu programa ficou assim:


import info_moedas

def converte_valor(valor_inicial, de_qual_moeda , para_qual_moeda):
    taxa_conversao = info_moedas.get_taxa_conversao(de_qual_moeda,
                                                    para_qual_moeda)
    valor_final = valor_inicial * taxa_conversao
    return valor_final

de_qual_moeda = input(‘Digite o símbolo internacional da moeda inicial: ‘)
valor_inicial = float(input(‘Digite o valor inicial: ‘))
para_qual_moeda = input(‘Digite o símbolo internacional da moeda final: ‘)

print(converte_valor(valor_inicial, de_qual_moeda, para_qual_moeda))

Fui testar o programa e logo quando eu o abri, olha o que apareceu:


AED - 784 - 2 - Dirham dos Emirados
AFN - 971 - 2 - Afegane
ALL - 008 - 2 - Lek
AMD - 051 - 0 - Dram
ANG - 532 - 2 - Florim
AOA - 973 - 2 - Kwanza
ARS - 032 - 2 - Peso Argentino
…
YER - 886 - 0 - Rial iemenita
ZAR - 710 - 2 - Rand
ZMW - 894 - 0 - Kwacha
ZWL - 932 - 2 - Dólar zimbabuano
Digite o símbolo internacional da moeda inicial: 

Mas o quê? Apareceram dezenas de linhas com informações de muitas moedas, mas eu não pedi por isso! Apesar disso tudo, no final ainda apareceu o que a gente colocou… que estranho!

Resolvi checar o código que baixei da internet, então, e lá pro final encontrei uma linha solta bem curta:


main()

Essa linha executa uma função declarada lá no info_moedas.py mesmo, cheia de instruções, incluindo as de imprimir toda essa informação que a gente recebeu. Tudo bem, achamos o código que faz isso, mas por que ele está sendo executado em nosso programa?

A questão está no funcionamento do import no Python. Quando importamos um arquivo Python, estamos de fato executando o código dentro dele.

Assim, a instrução import info_moedas executa a linha main() do arquivo que eu baixei, fazendo aparecer tudo isso em nosso programa. Mas como podemos evitar isso?

Uma solução mais intuitiva seria simplesmente apagar a chamada da função main() do arquivo info_moedas.py. Isso aparentemente resolveria nosso problema, mas quebraria o código original que eu encontrei, o que pode acabar nos trazendo mais outras complicações no futuro.

O ideal seria simplesmente dizer para o Python, ao importar o arquivo, não executar aquilo ali. Será que é possível fazer isso?

A variável name

No Python, arquivos .py são chamados de módulos. Cada módulo pode ser executado diretamente, como um programa em si, ou importado por outro módulo.

Precisamos, de alguma maneira, identificar essa diferença. Para isso, temos uma variável nativa que pode nos auxiliar nisso - a __name__, que nos indica o nome do contexto em que o módulo está rodando.

Resumindo, a variável __name__ representa o nome do módulo. Entretanto, quando o módulo é executado por si só como um programa, __name__ é definido para ’__main__’, diferente de quando o módulo é importado, no qual o valor fica de fato igual ao nome do módulo.

Vamos testar isso fazendo um simples programa que apenas imprime essa variável. Chamaremos de teste_name.py:


print(__name__)

Ao executarmos esse programa com python teste_name.py na linha de comando, olha o resultado:


__main__

Agora, se abrirmos o console do Python e importamos esse módulo, olha como fica:

import

Mudou! Com essa diferença, podemos saber quando um código está sendo executado no escopo principal de programa e quando está, na verdade, sendo importado. Assim, podemos tomar caminhos diferentes no código para cada uma dessas opções.

Banner da Escola de Programação: Matricula-se na escola de Programação. Junte-se a uma comunidade de mais de 500 mil estudantes. Na Alura você tem acesso a todos os cursos em uma única assinatura; tem novos lançamentos a cada semana; desafios práticos. Clique e saiba mais!

Usando if name == main para controle de escopo de execução

No Python, temos uma convenção idiomática para solucionar problemas como o do nosso tipo,em que precisamos que um código não execute se estiver sendo apenas importado.

Esta convenção se baseia nesse conceito da variável __name__, com uma condição que verifica se essa variável é igual a ’__main__’.

Em outras palavras, o que há é apenas uma verificação de se o programa está sendo executado por si só.

Agora podemos só alterar o código em info_moedas para colocar a chamada da função main() dentro do bloco dessa condição:


if __name__ == ‘__main__’:
    main()

Fui rodar o meu conversor de moedas e, dessa vez:


Digite o símbolo internacional da moeda inicial:

Toda aquela informação sumiu! Conseguimos o que queríamos ;).

Nesse caso esse condicional foi bastante útil pra gente, já que o código que estava rodando nem era nosso. Mas será que devemos usá-lo sempre? Quando e até que ponto ele pode ser bom?

Quando usar a checagem de escopo de execução?

Agora que já conhecemos essa técnica, como sabemos quando usá-la? Um impulso inicial pode ser de colocar em todos os nossos programas, afinal uma verificação nunca vai fazer muito mal, mas isso nem sempre é o ideal.

Normalmente, conseguimos atingir um maior nível de organização de nosso programa se dividirmos em módulos diferentes o código que faz as definições e o código que executa o que foi definido.

Muitas vezes, então, a melhor abordagem acaba sendo ter um módulo em que apenas se define algumas funções, mas não se executa nada fora delas, para então ser importado pelos módulos que as executarão.

Nem sempre, entretanto, isso é vantajoso para nosso programa, o que nos traz de volta para o começo. Nesse caso, a convenção que vimos pode ser muito útil, seja por simples garantia de que um código não executará em um import, seja porque de fato queremos um comportamento diferente para diferentes tipos de execução do programa.

Ainda há casos mais específicos em que este teste é de fato necessário, como no caso do módulo multiprocessing, que pode resultar em um RuntimeError.

Além disso, em testes simples e rápidos, essa única linha pode nos poupar bastante dor de cabeça!

Conclusão

Nesse post, aprendemos um pouco mais de como o import funciona no Python e um de seus possíveis problemas. Assim, vimos qual a solução comumente usada pelos desenvolvedores, e quando devemos usá-la.

E aí? Já conhecia essa técnica? Se quiser se aprofundar mais em Python, dê uma olhada nos nossos cursos da Alura sobre a linguagem e continue estudando!

Veja outros artigos sobre Programação