Escopo de Variáveis em Python
O escopo de uma variável define o contexto em que ela pode ser utilizada. No Python, existem dois tipos principais de escopo: global e local.
Escopo global
O escopo global indica que uma variável é global, ou seja, ela é definida fora de qualquer função e está acessível a todas as funções do programa. Por exemplo:
name = "Tom"
def say_hi():
print("Hello", name)
def say_bye():
print("Goodbye", name)
say_hi()
say_bye()Aqui, a variável name é global e tem escopo global. Ambas as funções definidas podem usá-la livremente.
Escopo local
Ao contrário das variáveis globais, uma variável local é definida dentro de uma função e só pode ser acessada por essa função, tendo, portanto, um escopo local:
def say_hi():
name = "Sam"
surname = "Johnson"
print("Hello", name, surname)
def say_bye():
name = "Tom"
print("Goodbye", name)
say_hi() # Hello Sam Johnson
say_bye() # Goodbye TomNesse exemplo, em cada uma das funções é definida uma variável local name. Embora essas variáveis tenham o mesmo nome, elas são variáveis distintas e estão acessíveis apenas dentro de suas respectivas funções. Além disso, na função say_hi(), a variável surname também é local, portanto, não pode ser usada na função say_bye().
Ocultando Variáveis Globais
name = "Tom"
def say_hi():
name = "Bob" # oculta a variável global
print("Hello", name)
def say_bye():
print("Goodbye", name)
say_hi() # Hello Bob
say_bye() # Goodbye TomNeste caso, a variável global name foi definida. No entanto, dentro da função say_hi(), há uma variável local com o mesmo nome. A função say_bye() usa a variável global, enquanto a função say_hi() utiliza a variável local, ocultando a variável global.
Se desejarmos alterar a variável global dentro de uma função, em vez de definir uma nova variável local, precisamos usar a palavra-chave global:
name = "Tom"
def say_hi():
global name
name = "Bob" # altera o valor da variável global
print("Hello", name)
def say_bye():
print("Goodbye", name)
say_hi() # Hello Bob
say_bye() # Goodbye Bobnonlocal
A palavra-chave nonlocal vincula um identificador a uma variável de um contexto envolvente mais próximo, exceto o global. Normalmente, nonlocal é usado em funções aninhadas, quando é necessário referenciar uma variável ou parâmetro da função externa. Vejamos um exemplo onde isso pode ser útil:
def outer(): # função externa
n = 5
def inner(): # função interna
print(n)
inner() # 5
print(n)
outer() # 5Aqui, a função interna inner() imprime o valor da variável n, que foi definida na função externa outer(). Quando chamamos outer(), veremos o número 5 duas vezes no console. No entanto, a função inner() apenas acessa o valor da variável.
Agora, vejamos o que acontece quando a função interna atribui um novo valor à variável n:
def outer(): # função externa
n = 5
def inner(): # função interna
n = 25
print(n)
inner() # 25
print(n)
outer() # 25 - inner
# 5 - outerQuando a função interna faz a atribuição n = 25, uma nova variável n é criada, ocultando a variável n da função externa outer(). Como resultado, teremos dois valores diferentes sendo impressos.
Para indicar que a função interna deve usar a variável da função externa, utilizamos a palavra-chave nonlocal:
def outer(): # função externa
n = 5
def inner(): # função interna
nonlocal n # indica que n é a variável da função externa
n = 25
print(n)
inner() # 25
print(n)
outer() # 25Com o uso de nonlocal, garantimos que a variável n da função interna se refere à variável da função externa, permitindo que a função interna modifique seu valor.