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
1.
if
__name__
=
=
‘__main__’:
a separar as nossas definições da parte em que as usamos. Por exemplo:
01.
import
turtle
02.
03.
def
poligono(posx,posy,orientacao,lado, num_lados):
04.
05.
06.
turtle.penup()
07.
turtle.goto(posx,posy)
08.
turtle.pendown()
09.
turtle.setheading(orientacao)
10.
11.
for
i
in
range(num_lados):
12.
turtle.forward(lado)
13.
turtle.left(
360
/
num_lados)
14.
turtle.hideturtle()
15.
16.
if
__name__
=
=
‘__main__’:
17.
poligono(
-
50
,
-
50
,
0
,
20
,
8
)
18.
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:
01.
>>>
import
math
02.
>>> id(math)
03.
4528111056
04.
>>> math
05.
<module
'math'
=
"
" from="
" '="
" usr="
" local="
" pythonbrew="
" pythons="
" python-3.2.3="
" lib="
" python3.2="
" lib-dynload="
" math.so'="
">
06.
>>> type(math)
07.
<
class
'module'
>
08.
>>>
09.
<
/
module>
Isso mesmo, têm identidade, valor e tipo. Mas têm outros atributos igualmente que podem ser identificados consultando o módulo.
1.
>>> dir(math)
2.
[
'__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'
]
3.
>>>
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.
1.
>>> math.__name__
2.
'math'
3.
>>>
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:
01.
>>>
import
poli
02.
>>> id(poli)
03.
4546041256
04.
>>> poli
05.
<module
'poli'
=
"
" from="
" '="
" volumes="
" work="
" __aulas="
" _____aulas="
" 2013_2014="
" iprp="
" aulas="
" 4="
" poli.py'="
">
06.
>>> type(poli)
07.
<
class
'module'
>
08.
>>> dir(poli)
09.
[
'__builtins__'
,
'__cached__'
,
'__doc__'
,
'__file__'
,
'__name__'
,
'__package__'
,
'poligono'
,
'turtle'
]
10.
>>> poli.__name__
11.
'poli'
12.
>>>
13.
<
/
module>
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.
1.
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.
1.
2.
3.
if
__name__
=
=
'__main__'
:
4.
print
(
'Execução'
)
5.
else
:
6.
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