Vamos para a segunda parte do nosso artigo sobre erros comuns quando estamos começando a programar em Python!
Se você ainda não viu a primeira parte, leia também para te ajudar a entender melhor este novo artigo!
Neste artigo vamos falar sobre escopos.
É, esta questão de escopos, que já costuma causar confusão em desenvolvedores iniciantes em praticamente toda linguagem também pode causar confusões no Python, especialmente se o iniciante já programa em outra linguagem.
Vejamos este exemplo:
x = 10
def func():
print x
Quando chamamos a função:>>> func()
10
Este é o comportamento esperado, e é muito usado em Python para definição de constantes.
Também podemos usar para alterar algumas globais, como por exemplo:
x = [1]
def func2():
x.append(0)
Chamando func2 teremos:
>>> x
[1]
>>> func2()
>>> x
[1, 0]
Mais uma vez funciona como o esperado.
Agora vejamos esta situação:
x = 1
def func3():
x = 10
>>> x
1
>>> func3()
>>> x
1
Oras, mas eu não alterei x dentro da função?
Não... na verdade, você criou uma variável local chamada x e atribuiu valor a ela no lugar da x global.
Vejamos então um outro caso:
x=1
def func4():
print x
x = 3
>>> func4()
Traceback (most recent call last):
File "" , line 1, in
func4()
File "" , line 3, in func4
print x
UnboundLocalError: local variable 'x' referenced before assignment
Mas como? Eu coloquei o print antes de atribuir valor para a variável? Ele não deveria ter mostrado o valor da variável de fora da função?
Pois é, NÃO.
Ao contrário do que muitos pensam, Python não executa o programa linha a linha, mas "statement by statement", verifique isto abrindo o shell do python e digitando "def func():".
O console fica esperando você terminar o "statement" pra só depois interpretar realmente o que você escreveu.
Além disto, o interpretador não executa a função quando ela é interpretada, somente instancia o objeto função. A função somente será executada quando esta for chamada.
Assim, ao instanciar a função, o interpretador reserva as variáveis que são usadas lá dentro, sem avaliar onde e como esta variável é usada dentro da função. Isto será avaliado somente durante a execução da função.
Um exemplo de que para o interpretador não importa o que é feito com as variáveis no momento em que a função é instanciada:
x = 1
def func5(y):
if y >1:
print x
x = 4
A execução desta função resulta na mesma exceção do exemplo anterior, assim como este exemplo:
x = 1
def func6():
print x
if False:
x = 3
Há basicamente 2 soluções para estes casos:
Uso da keyword global:
x = 1
def func7():
global x
print x
x = 5
>>> x
1
>>> func7()
1
>>> x
5
Esta keyword permite ao interpretador saber que a variável X é a variável global, não a local, assim, quando se atribui um novo valor à variável X, é alterado o valor da variável global, sem ser criada uma nova variável no escopo local.
Esta aproximação é menos usada e pouco recomendada. Qualquer pessoa que fez um bom curso de programação sabe que o uso de variáveis globais não é uma boa prática, e é assim em Python também.
A opção mais indicada é então:
Definir variáveis que serão usadas globalmente como atributo de uma classe:
class Xis():
x = 1
def func8():
print Xis.x
Xis.x = 2390
Neste caso, não há como ter efeitos indesejados, pois todo e qualquer acesso à variável x será qualificado com o nome da classe.
Espero que tenha ajudado aos iniciantes e mesmo pessoas mais experientes que ainda não entendiam muito bem como funcionam escopos em Python.
Um grande abraço e até o próximo artigo!
*Abaixo link para o post em que me inspirei para criar este aqui.
Python: Common Newbie Mistakes, Part 2

Nenhum comentário:
Postar um comentário