Namespace e escopo do Python
Espaço de nomes e escopo do Python
Neste tutorial, você aprenderá sobre namespace, mapeamento de nomes para objetos e escopo de uma variável.
O que é nome em Python?
Se você já leu 'The Zen of Python' (digite
import this
no interpretador Python), a última linha afirma:Os namespaces são uma ótima ideia -- vamos fazer mais deles! Então, quais são esses namespaces misteriosos? Vamos primeiro olhar para o que é o nome. Nome (também chamado de identificador) é simplesmente um nome dado aos objetos. Tudo em Python é um objeto. Nome é uma maneira de acessar o objeto subjacente.
Por exemplo, quando fazemos a atribuição
a = 2
, 2
é um objeto armazenado na memória e a é o nome com o qual o associamos. Podemos obter o endereço (na RAM) de algum objeto através da função interna id()
. Vejamos como usá-lo.
# Note: You may get different values for the id
a = 2
print('id(2) =', id(2))
print('id(a) =', id(a))
Saída
id(2) = 9302208 id(a) = 9302208
Aqui, ambos se referem ao mesmo objeto
2
, então eles têm o mesmo id()
. Vamos tornar as coisas um pouco mais interessantes.
# Note: You may get different values for the id
a = 2
print('id(a) =', id(a))
a = a+1
print('id(a) =', id(a))
print('id(3) =', id(3))
b = 2
print('id(b) =', id(b))
print('id(2) =', id(2))
Saída
id(a) = 9302208 id(a) = 9302240 id(3) = 9302240 id(b) = 9302208 id(2) = 9302208
O que está acontecendo na sequência de etapas acima? Vamos usar um diagrama para explicar isso:
Inicialmente, um objeto
2
é criado e o nome a está associado a ele, quando fazemos a = a+1
, um novo objeto 3
é criado e agora a está associado a este objeto. Observe que
id(a)
e id(3)
têm os mesmos valores. Além disso, quando
b = 2
for executado, o novo nome b é associado ao objeto anterior 2
. Isso é eficiente, pois o Python não precisa criar um novo objeto duplicado. Essa natureza dinâmica da vinculação de nomes torna o Python poderoso; um nome pode se referir a qualquer tipo de objeto.
>>> a = 5
>>> a = 'Hello World!'
>>> a = [1,2,3]
Todos estes são válidos e a irá se referir a três tipos diferentes de objetos em diferentes instâncias. Funções também são objetos, então um nome pode se referir a elas também.
def printHello():
print("Hello")
a = printHello
a()
Saída
Hello
O mesmo nome a podemos fazer referência a uma função e podemos chamar a função usando este nome.
O que é um namespace em Python?
Agora que entendemos o que são nomes, podemos passar para o conceito de namespaces.
Simplificando, um namespace é uma coleção de nomes.
Em Python, você pode imaginar um namespace como um mapeamento de cada nome que você definiu para os objetos correspondentes.
Diferentes namespaces podem coexistir em um determinado momento, mas são completamente isolados.
Um namespace contendo todos os nomes internos é criado quando iniciamos o interpretador Python e existe enquanto o interpretador for executado.
Esta é a razão pela qual funções internas como
id()
, print()
etc. estão sempre disponíveis para nós em qualquer parte do programa. Cada módulo cria seu próprio namespace global. Esses namespaces diferentes são isolados. Assim, o mesmo nome que pode existir em módulos diferentes não colide.
Os módulos podem ter várias funções e classes. Um namespace local é criado quando uma função é chamada, que tem todos os nomes definidos nela. Semelhante é o caso da classe. O diagrama a seguir pode ajudar a esclarecer esse conceito.
Escopo da variável Python
Embora existam vários namespaces exclusivos definidos, talvez não possamos acessar todos eles de todas as partes do programa. O conceito de escopo entra em jogo.
Um escopo é a parte de um programa de onde um namespace pode ser acessado diretamente sem qualquer prefixo.
A qualquer momento, há pelo menos três escopos aninhados.
- Escopo da função atual que tem nomes locais
- Escopo do módulo que tem nomes globais
- Escopo externo que possui nomes integrados
Quando uma referência é feita dentro de uma função, o nome é pesquisado no namespace local, depois no namespace global e finalmente no namespace interno.
Se houver uma função dentro de outra função, um novo escopo será aninhado dentro do escopo local.
Exemplo de escopo e namespace em Python
def outer_function():
b = 20
def inner_func():
c = 30
a = 10
Aqui, a variável a está no namespace global. Variável b está no namespace local de
outer_function()
e c está no namespace local aninhado de inner_function()
. Quando estamos em
inner_function()
, c é local para nós, b é não local e a é global. Podemos ler e atribuir novos valores a c mas só pode ler b e um de inner_function()
. Se tentarmos atribuir um valor a b , uma nova variável b é criado no namespace local que é diferente do não local b . A mesma coisa acontece quando atribuímos um valor a a .
No entanto, se declararmos a como global, todas as referências e atribuições vão para o global a . Da mesma forma, se quisermos religar a variável b , ele deve ser declarado como não local. O exemplo a seguir esclarecerá melhor isso.
def outer_function():
a = 20
def inner_function():
a = 30
print('a =', a)
inner_function()
print('a =', a)
a = 10
outer_function()
print('a =', a)
Como você pode ver, a saída deste programa é
a = 30 a = 20 a = 10
Neste programa, três variáveis diferentes a são definidos em namespaces separados e acessados de acordo. Enquanto estiver no programa a seguir,
def outer_function():
global a
a = 20
def inner_function():
global a
a = 30
print('a =', a)
inner_function()
print('a =', a)
a = 10
outer_function()
print('a =', a)
A saída do programa é.
a = 30 a = 30 a = 30
Aqui, todas as referências e atribuições são para o global a devido ao uso da palavra-chave
global
. python
- Palavras-chave e identificadores do Python
- Declaração Python, Recuo e Comentários
- Variáveis, constantes e literais do Python
- Conversão de tipo Python e conversão de tipo
- Entrada, Saída e Importação do Python
- Operadores Python
- Variáveis globais, locais e não locais do Python
- Números Python, Conversão de Tipos e Matemática
- Gerenciamento de diretórios e arquivos Python
- Erros do Python e exceções incorporadas