Quando escrevemos um programa em Python, seja num vulgar editor de texto seja recorrendo ao editor de um ambiente integrado de desenvolvimento como o Wingware, foi-vos dito para colocar o código
if __name__ == ‘__main__’:
a separar as nossas definições da parte em que as usamos. Por exemplo:
import turtle
def poligono(posx,posy,orientacao,lado, num_lados):
""" Desenha um poligono de num_lados ."""
# Prepara
turtle.penup()
turtle.goto(posx,posy)
turtle.pendown()
turtle.setheading(orientacao)
# Desenha
for i in range(num_lados):
turtle.forward(lado)
turtle.left(360/num_lados)
turtle.hideturtle()
if __name__ == ‘__main__’:
poligono(-50,-50,0,20,8)
turtle.exitonclick()
Será que é obrigatório fazer assim? Não, claro que não. Já vimos que podemos não usar a construção condicional
if no final e o nosso programa corre na mesma. Então porque usamos?? Vamos tentar explicar.
Sabemos que a linguagem Python pode ser estendida, adicionando novos comandos guardados em módulos. Esses módulos, para podermos usar as constantes e comando que nele estão definidos, têm que ser importados. Os módulos são tecnicamente objectos e, como todos os objectos têm um conjunto de atributos:
>>> import math
>>> id(math)
4528111056
>>> math
>>> type(math)
< class 'module' >
>>>
Isso mesmo, têm identidade, valor e tipo. Mas têm outros atributos igualmente que podem ser identificados consultando o módulo.
>>> dir(math)
['__doc__', '__file__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
>>>
Um dos atributos é o nome (__name__). Quando importamos um módulo é criado um espaço de nomes e __name__ fica associado a um objecto do tipo cadeia de caracteres que define o nome do módulo, após a importação. E podemos saber qual é consultando como habitualmente qual o valor do objecto associado ao nome.
>>> math.__name__
'math'
>>>
Quando importamos o nome do módulo é igual ao nome do ficheiro que implementa o módulo depois de retirada a extensão do ficheiro.
Regressemos agora aos nosso ficheiros com código Python. São criados com a extensão ‘
.py’. Também eles têm a natureza de ... módulos. Podem por isso ser importados, e têm os mesmos atributos:
>>> import poli
>>> id(poli)
4546041256
>>> poli
>>> type(poli)
< class 'module' >
>>> dir(poli)
['__builtins__', '__cached__', '__doc__', '__file__', '__name__', '__package__', 'poligono', 'turtle']
>>> poli.__name__
'poli'
>>>
Uma vez mais um ficheiro com código Python escrito por nós
quando importado tem um nome igual ao nome do ficheiro depois de retirada a extensão. Olhando para o código do ficheiro indicado acima, o leitor atento terá verificado que a chamada à definição
polígono e ao método
exitonclick() não ocorreram. E porquê? Por que serem executadas é preciso que o teste.
if __name__ == ‘__main__’:
seja verdadeiro, o que não acontece pois, como acabámos de ver, quando um módulo/ficheiro é importado o seu nome é igual ao do módulo!
Vejamos agora o que acontece quando em vez de importar executamos o módulo/ficheiro.
Agora sim, aparece o polígono !
Conclusão. O recurso à separação do nosso ficheiro em duas partes, uma onde definimos o código e a outra onde executamos condicionalmente algumas instruções, permite que um ficheiro possa ter dois comportamentos diferentes, quando importamos ou quando mandamos correr/executar o ficheiro. Mas porque é que podemos querer este duplo comportamento? Bem, se o nosso programa for apenas para ser executado por nós e nunca importado não precisamos. Mas se por acaso nós, ou alguém, quiser usar algumas das definições que estão no nosso ficheiro para fins diversos dos nossos então precisamos de usar a instrução condicional a separar as duas partes: definição e uso. Refira-se ainda que muitos programadores que desenvolvem módulos complexos para Python usam esta facilidade para colocar a seguir ao
if um conjunto de chamadas às definições que ilustram o que fazem as diferentes instruções contidas na primeira parte do módulo.
Se ainda tem duvidas e quer testar com um código minimalista então crie um ficheiro com o seguinte conteúdo.
""" name_main.py."""
if __name__ == '__main__':
print('Execução')
else:
print('Importação')
salve-o com um nome apropriado (por exemplo
name_main.py), e teste em duas situações: importe o módulo e execute o programa.
Sem comentários:
Enviar um comentário