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 Tom
Nesse 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 Tom
Neste 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 Bob
nonlocal
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() # 5
Aqui, 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 - outer
Quando 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() # 25
Com 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.