Entendendo se __name__ == ‘__main__’ em Python

Neste guia, você entenderá a funcionalidade e o significado de if __name__ == ‘__main__’ em Python.

Você já vasculhou uma base de código Python com módulos diferentes?

Se sim, você provavelmente teria encontrado se __name__ == ‘__main__’ condicional em um ou mais módulos. Nos próximos minutos, desmistificaremos o que a condicional acima significa e veremos um exemplo em que ela pode ser útil.

Vamos começar!

Qual é o significado de __name__ em Python?

Em Python, um módulo é um arquivo .py que contém definições de funções, um conjunto de expressões a serem avaliadas e muito mais. Por exemplo, se temos um arquivo chamado hello_world.py, nos referimos a ele como o arquivo hello_world.py ou o módulo hello_world.

Quando você executa um módulo Python, o interpretador Python define os valores para algumas variáveis ​​especiais antes da execução: __name__ é uma delas. A chave para entender o significado de __name__ é entender como as importações funcionam em Python.

📁 Baixe o código desta seção aqui.

Vá para a pasta example-1. Temos o arquivo module1.py. A variável __name__ está no namespace do módulo atual.

Este módulo imprime uma linha seguida pelo valor da variável __name__.

# example-1/module1.py
print("This is module1.")
print(f"The __name__ variable of module 1 is: {__name__}.")

Agora, vamos executar o módulo1 a partir da linha de comando.

$ python module1.py

Na saída, vemos que a variável __name__ está definida como __main__.

This is module1.
The __name__ variable of module 1 is: __main__.

Importando módulos em Python

Além de executar um módulo Python, às vezes você pode querer usar a funcionalidade de outro módulo Python dentro do módulo atual. Python facilita isso por meio de importações.

  Como usar extensões de ação e compartilhamento no iPhone e iPad

As importações permitem que você reutilize a funcionalidade de outro módulo — importando-a para o escopo do módulo atual — sem precisar reescrever o código.

O arquivo module2.py contém o seguinte. Nós importamos o módulo1 para dentro. módulo2.

# example-1/module2.py

import module1 # module1 is imported

print(f"This is module2")
print(f"The __name__ variable of module2 is: {__name__}.")

Executamos o module2.py e observamos a saída.

$ python module2.py

Na saída abaixo:

  • Vemos que o módulo1 é executado nos bastidores quando o importamos dentro do módulo2, e a saída correspondente é impressa.
  • Mas desta vez, a variável __name__ não é __main__ mas module1.
  • Como executamos o módulo2 diretamente, a variável __name__ correspondente ao módulo agora é __main__.
Output

This is module1.
The __name__ variable of module 1 is: module1.
This is module2
The __name__ variable of module2 is: __main__.

💡 Ideia chave:

– Se um módulo for executado diretamente, sua variável __name__ será definida como igual a __main__.

– Se um módulo for importado dentro de outro módulo, seu __name__ será definido como o nome do módulo.

Exemplo de if __name__==’__main__’ em Python

Na seção, veremos um caso de uso prático da condicional if __name__ == ‘__main__’. Vamos definir uma função simples e, em seguida, escrever testes de unidade para verificar se a função está funcionando conforme o esperado.

📁 Baixe o código e acompanhe.

O código para esta seção pode ser encontrado na pasta example-2.

Aqui, add.py é um arquivo Python que contém a definição da função add_ab(). A função add_ab() recebe dois números quaisquer e retorna sua soma.

# example-2/add.py

def add_ab(a,b):
    return a + b

Usaremos o módulo unittest do Python para testar a função add_ab().

Escrevendo casos de teste para uma função Python

Veja o trecho de código abaixo, contendo o conteúdo do módulo test_add.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)
    

O código acima faz o seguinte:

  • Importa o módulo unittest integrado do Python
  • Importa a função add_ab() do módulo add
  • Define a classe de teste TestAdd e um conjunto de casos de teste como métodos dentro da classe de teste
  Como melhorar as configurações de qualidade e largura de banda da sua câmera Nest

Para configurar testes de unidade para seu código, você deve primeiro definir uma classe de teste que herda de unittest.TestCase. Todos os casos de teste devem ser especificados como métodos dentro da classe e devem começar com test_.

Nota: Se você não nomear os métodos como test_, verá que os testes correspondentes não serão detectados e, portanto, não serão executados.

Agora vamos tentar executar o módulo test_add do terminal.

$ python test_add.py

Você verá que não há saída e nenhum dos testes foi executado.

Por que isso acontece? 🤔

Isso ocorre porque para executar os testes unitários, você deve executar unittest como módulo principal enquanto executa test_add.py, usando o comando abaixo.

$ python -m unittest test_add.py

Ao executar o comando detalhado acima, vemos que todos os três testes foram executados com sucesso.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

No entanto, será conveniente executar os testes quando este módulo test_add for executado, sim? Vamos aprender como fazer isso na próxima seção.

Usando if __name__ == ‘__main__’ para executar unittest como o módulo principal

Se você quiser executar todos os testes de unidade quando o módulo for executado diretamente, poderá adicionar o condicional.

# example-2/test_add.py

import unittest
from add import add_ab

class TestAdd(unittest.TestCase):
    def test_add_23(self):
        self.assertEqual(add_ab(2,3), 5)
    
    def test_add_19(self):
        self.assertEqual(add_ab(1,9), 10)
    
    def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), -6)

# Run unittest as the main module
if __name__ == '__main__':
        unittest.main()

A condicional no trecho de código acima informa ao interpretador Python: Se este módulo for executado diretamente, execute o código interno. unittest.main().

  Como os hologramas funcionam no palco?

Você pode executar o módulo test_add após adicionar as duas linhas de código acima.

$ python test_add.py

▶️ Executar o módulo test add diretamente agora executa todos os três testes que definimos.

Output
...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

A saída acima OK indica que todos os testes foram executados com sucesso. Os três pontos… indicam que três testes foram executados e todos passaram.

Agora, vamos alterar o valor de retorno esperado test_add_1_minus7 para 8. Como a função retorna – 6 nesse caso, deve haver um teste com falha.

def test_add_1_minus7(self):
        self.assertEqual(add_ab(1,-7), 8)

Como visto na saída abaixo, obtemos .F., dos três testes, padrão um deles falhou (o segundo teste), e no traceback, obtemos um AssertionError informando – 6 != 8.

Output
.F.
======================================================================
FAIL: test_add_1_minus7 (__main__.TestAdd)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_add.py", line 12, in test_add_1_minus7
    self.assertEqual(add_ab(1,-7), 8)
AssertionError: -6 != 8

----------------------------------------------------------------------
Ran 3 tests in 0.021s

FAILED (failures=1)

Uma coisa importante a ser observada é que os testes não são executados necessariamente na mesma ordem em que são especificados na classe de teste. No exemplo acima, test_add_1_minus7 é definido como o terceiro método na classe de teste, mas o teste correspondente foi executado em segundo lugar.

Resumindo

Espero que este tutorial tenha ajudado você a entender como a condicional if __name__ == ‘__main__’ funciona em Python.

Aqui está uma rápida recapitulação das principais conclusões:

  • O interpretador Python define a variável __name__ antes de executar o script Python.
  • Quando você executa um módulo diretamente, o valor de __name__ é __main__.
  • Quando você importa um módulo dentro de outro script Python, o valor de __name__ é o nome do módulo.
  • Você pode usar if __name__ == ‘__main__’ para controlar a execução e quais partes do módulo são executadas durante execuções diretas e importadas, respectivamente.

Em seguida, confira este guia detalhado sobre conjuntos de Python. Bom aprendizado!🎉