Tudo o que você queria saber sobre o escopo no Python, mas teve vergonha de perguntar

Antecipando o início de um novo tópico no curso "Python Developer" , decidimos falar sobre o escopo no Python. O que aconteceu com isso? - Leia o material abaixo.




Hoje falaremos sobre importantes fundamentos teóricos que devem ser entendidos e lembrados para se escrever um código competente, legível e bonito. Vamos falar sobre o escopo das variáveis. Este artigo será útil não apenas para iniciantes, mas também para programadores experientes que vieram para o Python de outra linguagem e desejam entender sua mecânica.

Os escopos determinam em qual parte do programa podemos trabalhar com uma variável específica e da qual a variável está "oculta". É extremamente importante entender como usar apenas os valores e variáveis ​​que precisamos e como o intérprete de linguagem se comporta. Também veremos como contornar as restrições impostas pelo escopo às ações com variáveis. No Python, existem até três escopos:

  • Local
  • Global
  • Não-local

O último escopo não-local foi adicionado no Python 3.

Geralmente, estamos falando de escopo quando familiarizados com funções. Usando o exemplo deles, consideraremos o trabalho do escopo das variáveis.

Escopo local


Considere uma função que exibe um some_listelemento de lista por elemento:

def print_list(some_list):
    for element in some_list:
        print(element)

Aqui estão elemente some_listvariáveis ​​locais que são visíveis apenas dentro da função e que não podem ser usadas fora dela com os valores que foram atribuídos a eles dentro da função durante sua operação. Ou seja, se chamarmos o corpo principal do programa print(element), obteremos um erro:

NameError: name 'element' is not defined


Agora, faremos o seguinte:

def print_list(some_list):
    for element in some_list:
        print(element) 

element = 'q'
print_list([1, 2, 3])
print(element) 


E temos:

1
2
3
q

Aqui a variável elementdentro da função e a variável com o mesmo nome fora dela são duas variáveis ​​diferentes, seus valores não se cruzam e não se trocam. Eles são chamados da mesma forma, mas se referem a diferentes objetos na memória. Além disso, um elemento nomeado variável dentro da função permanece enquanto a função é executada e não mais. Mas tenha cuidado para atribuir o mesmo nome às variáveis ​​locais e globais, agora mostrarei o porquê:

def print_list(some_list):
    for element in sudden_list:
        print(element) 

sudden_list = [0, 0, 0]
print_list([1, 2, 3])

Resultado:

0
0
0

Observe que o intérprete não nos indicou erros. E tudo porque sudden_listestá no escopo global, ou seja, de dentro da função print_list, podemos acessá-la, porque de dentro você pode ver o que está acontecendo lá fora. Por esse motivo de mecânica do trabalho, tente nomear variáveis ​​locais dentro da função de maneira diferente da que você chama de variáveis ​​no escopo global.

É importante falar sobre constantes aqui. Não há diferença para o interpretador Python o que você chama de variável; portanto, o código acima seria melhor reescrito da seguinte maneira:

SUDDEN_LIST = [0, 0, 0]

def print_list(some_list):
    for element in SUDDEN_LIST:
        print(element) 

print_list([1, 2, 3]) 

Agora tudo está no lugar. O problema é que, em Python, você não pode definir estritamente uma constante como um objeto que não deve ser modificado. Portanto, a maneira como você usa o valor de uma variável cujo nome está escrito em letras maiúsculas permanece apenas em sua consciência. Outra questão é que, dessa maneira, a variável gravada deixará claro para quem lê seu código que a variável não será alterada em lugar algum. Ou pelo menos não deveria.

Âmbito global


Python tem uma palavra-chave globalque permite alterar o valor de uma variável global de dentro de uma função. É escrito antes do nome da variável, que será considerado global dentro da função. Como você pode ver no exemplo, agora o valor da variável está candyaumentando e observe que não a passamos como argumento para a função get_candy().

candy = 5

def get_candy():
    global candy 
    candy += 1
    print('  {} .'.format(candy))
    
get_candy()
get_candy()
print(candy)


Como resultado, obtemos:


	  6 .
  7 .
7


No entanto, alterar o valor de uma variável global de dentro da função não é a melhor prática, e é melhor não fazê-lo, porque não contribui para a legibilidade do código. Quanto menor o que acontece dentro da função dependerá do escopo global, melhor.

Life hack : para não sofrer a nomeação de variáveis, você pode colocar o código principal do programa em uma função main(); todas as variáveis ​​que serão declaradas nessa função permanecerão locais e não prejudicarão o escopo global, aumentando a probabilidade de erro.

Escopo não-local


Este conceito apareceu no Python 3 junto com a palavra-chave nonlocal. A lógica de sua escrita é quase a mesma que a de global. No entanto, nonlocalhá um recurso. NonlocalÉ mais frequentemente usado em funções aninhadas quando queremos fazer o intérprete entender que, para uma função aninhada, uma determinada variável não é local, mas não é global no sentido geral.

def get_candy():
    candy = 5
    def increment_candy(): 
        nonlocal candy
        candy += 1
        return candy
    return increment_candy
    
result = get_candy()()
print(' {} .'.format(result))

Resultado:

 6 .

Quão útil é para você decidir por si mesmo. Você pode encontrar mais exemplos aqui .

Como conclusão, várias regras podem ser formuladas:

  1. De dentro da função existem variáveis ​​visíveis que foram definidas dentro e fora dela. As variáveis ​​definidas internamente são locais e externamente globais.
  2. Fora das funções, nenhuma variável definida dentro delas é visível.
  3. , global.
  4. nonlocal , , .

É isso, espero que este material tenha sido útil para você, e tenha lançado pelo menos um pouco de luz sobre como o escopo funciona no Python. Depois de lidar com os escopos, você criará outro nosso no caminho da criação de código bonito e legível.

Também quero convidar todos para um webinar gratuito da OTUS, onde estudaremos uma ferramenta como a anotação de tipo no Python: discuta as razões pelas quais muitas pessoas a subestimam, considere vários exemplos da prática militar quando a anotação de tipo pode salvar ou salvar a situação. Vamos falar sobre como e quando implementar a verificação de tipo em seus projetos .

All Articles