- Namespaces =======
1.1. Conceito
Namespaces são locais que armazenam mapeamentos entre nomes de variáveis e seus valores correspondentes.
1.2. Classificação
1.2.1. Namespace Incorporado
Namespace criado pelo interpretador Python durante sua execução, contendo palavras-chave como def, if, else, len, entre outras.
Início do interpretador Python --- criação Fechamento do interpretador Python --- liberação
1.2.2. Namespace Global
Todos os nomes criados durante a execução de um arquivo Python são armazenados no namespace global (código fora das funções).
apelido = 'CR7' # nome da variável armazenado no namespace global
def autenticar(): # nome da função armazenado no namespace global
pass
if True:
valor = 42 # nome da variável armazenado no namespace global
for item in range(5): # nome da variável armazenado no namespace global
pass
while True:
contador = 100 # nome da variável armazenado no namespace global
Início da execução do arquivo Python --- criação Fim da execução do arquivo Python --- liberação
1.2.3. Namespace Local
Nomes criados durante a execução do código dentro de funções são armazenados no namespace local.
def cadastrar():
usuario = 'zico' # nome armazenado no namespace local
Início da execução do corpo da função --- criação Fim da execução do corpo da função --- liberação
1.3. Ordem de Busca no Namespace
Ao procurar por nomes, é crucial entender em qual namespace estamos atualmente.
1. Se estivermos no namespace local:
Namespace local ------------> Namespace global ------------> Namespace incorporado
2. Se estivermos no namespace global:
Namespace global ------------> Namespace incorporado
(só é possível buscar para camadas externas, não para camadas internas)
- Ordem de execução do código
# Namespaces locais que não são aninhados não interferem entre si
def funcao_alpha():
nome = 'CR7'
def funcao_beta():
idade = 38
print(nome) # Erro: nome não definido
funcao_alpha()
funcao_beta()
- Escopos =======
2.1. Conceito
Escopo é a abrangência na qual um namespace pode operar, ou seja, o intervalo onde o nome de uma variável e seu valor podem ser acessados (local onde a variável é definida e pode ser localizada).
2.2. Classificação
Escopo Incorporado (Built-in)
Incorporado: variáveis internas do interpretador, como int, str, etc. Abrangência: todos os módulos (arquivos) Python não possui escopo de bloco. Esccopo de bloco: variáveis dentro de blocos de código, como após if, while, for.
Disponível em qualquer fase e posição do programa (globalmente válido)
Escopo Global (Global)
Global: variáveis declaradas no nível superior de um módulo possuem escopo global. Do ponto de vista externo, variáveis globais de um módulo são atributos do objeto módulo, limitadas a um único arquivo de módulo.
Abrangência: módulo atual (arquivo)
Disponível em qualquer fase e posição do programa (globalmente válido)
Escopo Local (Local)
Local (variável local): existência temporária, dependente da função que criou o escopo local.
Enquanto a função existe, a variável local existe; quando a função deixa de existir, a variável local também deixa de existir. Abrangência: todo o corpo da função atual
Geralmente válido apenas em seus respectivos namespaces locais (localmente válido)
Escopo Aninhado (Enclosed)
Aninhado: geralmente quando há funções aninhadas, é o escopo de variáveis da função externa. Abrangência: função de fechamento
2.3. Exemplos de Escopos
Exemplo de escopo incorporado:
Variáveis pré-carregadas no escopo incorporado, como os
import os
Exemplo de escopo global:
Variáveis definidas por você mesmo no arquivo
numero = 123
Exemplo de escopo local e aninhado:
idade = 25<br></br>
# Escopo local: todas as variáveis definidas dentro de funções ou classes
# Escopo aninhado: quando há funções aninhadas, escopo das variáveis da função externa
def pessoa():
idade = 32 # Esta idade é de escopo local para a função pessoa, e aninhada para a função interna
print(f" Minha idade é {idade}")
def interna():
idade = 42 # Esta idade é de escopo local para a função interna
print(f" Idade interna: {idade}")
interna()
pessoa()
print(f" Idade global: {idade}")
Ordem de carregamento de escopos: incorporado --- global --- externo --- interno Ordem de busca: interno --- externo --- global --- incorporado A ordem de busca segue a regra LEGB L ---> local local mais interno da função E ---> enclosed aninhado, função externa em relação à função interna G ---> global B ---> built-in incorporado
2.4. Declarações de Escopo
Dicionários são tipos de dados mutáveis, ao modificar dicionários estamos modificando o mesmo conteúdo no espaço de endereços de memória
[Resumo]
[1] Namespace é o lugar que armazena mapeamentos entre nomes de variáveis e seus valores: incorporado, global, local
[2] Escopo é a abrangência onde o mapeamento entre nome de variável e valor é válido: incorporado, global, local, aninhado
[3] Se uma modificação local de dados imutáveis globais for necessária, use global para elevar o nível do escopo atual
Se uma modificação de dados imutáveis locais por uma função aninhada for necessária, use nonlocal para elevar o nível do escopo
Escopos aninhados não podem modificar dados imutáveis do escopo global
2.5. Modificação Local de Dados Imutáveis Globais
Modificação local de dados mutáveis globais --- sem necessidade de tratamento --- o endereço de memória do tipo de dado mutável não muda
Tipos de dados imutáveis --- atribuição de novo valor a um tipo de dado imutável
Em geral, escopos locais não podem modificar tipos imutáveis globais
x = 100
print(x, id(x)) # 100 1401231234568
def alterar_valor():
x = 200
print(x, id(x)) # 200 1401231234640
alterar_valor()
print(x, id(x)) # 100 1401231234568
Uso da palavra-chave global em escopo local para modificar tipos imutáveis globais
x = 100
print(x, id(x)) # 100 1401231234568
def alterar_valor():
global x # Uso de global no escopo local modifica a variável global x
x = 200
print(x, id(x)) # 200 1401231234640
alterar_valor()
print(x, id(x)) # 200 1401231234640
Modificação direta local de dados mutáveis globais
lista = [100]
print(lista, type(lista), id(lista)) # [100] <class 'list'> 2664527109952
def alterar_lista():
lista.append(200) # Modificação local de tipo mutável global, endereço de memória não muda
print(lista, id(lista)) # [100, 200] 2664527109952
alterar_lista()
print(lista, id(lista)) # [100, 200] 2664527109952
2.6. Modificação de Dados Imutáveis Globais por Funções Aninhadas
Funções internas não podem modificar diretamente tipos imutáveis globais
x = 100
print(x, id(x)) # 100 2409063970416
def alterar_valor():
def interna():
x = 200
print('Função interna', x, id(x)) # Função interna 200 2409063970480
interna()
alterar_valor()
print(x, id(x)) # 100 2409063970416
Funções internas podem usar a palavra-chave global para modificar tipos imutáveis globais (quando não há variável com mesmo nome no escopo externo)
x = 100
print(x, id(x)) # 100 2892394985072
def alterar_valor():
def interna():
global x # Uso de global na função interna modifica o imutável global
x = 200
print('Função interna', x, id(x)) # Função interna 200 2892394985136
interna()
alterar_valor()
print(x, id(x)) # 200 2892394985136
Funções internas usando a palavra-chave global para modificar tipos imutáveis globais (quando há variável com mesmo nome no escopo externo)
x = 100
print(x, id(x)) # 100 2465023850096
def alterar_valor():
x = 50
print(x, id(x)) # 50 2465022807728
def interna():
global x # Global faz com que todos os x abaixo se tornem x global
print('Função interna', x, id(x)) # Função interna 100 2465023850096
x = 200
print('Função interna', x, id(x)) # Função interna 200 2465023850160
interna()<br></br>
alterar_valor()
print(x, id(x)) # 200 2465023850160
Funções internas usando a palavra-chave nonlocal para modificar tipos imutáveis do escopo externo
x = 100
print(x, id(x)) # 100 2836141569648
def alterar_valor():
x = 50
print(x, id(x)) # 50 2836140527280
def interna():
nonlocal x
print('Função interna', x, id(x)) # nonlocal faz com que a função interna mantenha consistência com o x da função externa
# Função interna 50 2836140527280
x = 200
print('Função interna', x, id(x)) # Função interna 200 2836141569712
interna()
alterar_valor()
print(x, id(x)) # 100 2836141569648
2.7. Resumo de global vs nonlocal
global declara variáveis globais, carregando tipos de dados imutáveis globais
nonlocal declara variáveis da função externa para funções internas, carregando variáveis da função externa da função interna