Namespaces

Introdução

O que é um namespace? Isto de certeza é o que te deve estar a passar pela cabeça agora, no entanto apesar de não ser algo extraordinariamente complicado de explicar, é ainda difícil, isto porque cada linguagem o faz de forma diferente O conceito é bastante simples, um namespace é um espaço ou uma região, dentro de um programa, onde um nome (uma variável uma função, etc..) é considerado válido.

Este conceito apareceu porque as primeiras linguagens de programação (como é o caso do BASIC) só tinham as chamadas Global Variables, isto é uma variável que estaria presente durante todo o programa - mesmo dentro das funções. Ora isto tornava a manutenção de programas muito longos uma tarefa muito difícil, isso ficou conhecido como side-effect (efeito secundário). Para resolver o problema as novas linguagens de programação criaram o conceito de namespace ( C++ levou este conceito aos extremos permitindo que o próprio programador pudesse criar o seu namespace em qualquer parte do programa. Isso é muito bom para quem cria bibliotecas e quer manter os nomes das suas funções únicas, quando misturadas com bibliotecas de outros programadores).

Como o Python encara isto

No Python cada módulo cria o seu próprio namespace. Para termos acesso a esses nomes temos que precede-las pelo nome do modulo ou então explicitamente importar os nomes que queremos usar para dentro do nosso módulo. Mas isso não é nada de novo, visto que é o que temos andado a fazer com o sys e string. De certa forma as definições class também criam seu próprio namespace mas para aceder a esses nomes temos que usar o nome da instance variável ou então o classname..

No Python existem apenas 3 tipos de namespace (ou scopes):

  1. Local scope - nome definido dentro de uma função, ou dentro de um método
  2. Module scope - nomes definidos dentro de um ficheiro
  3. Builtin scope - nomes definidos dentro do próprio Python, estando portanto, constantemente disponíveis.

So far so good. Então mas o que acontece quando temos duas variáveis diferentes em namespaces diferentes, mas com o mesmo nome? Ou então o que acontece quando se se referencia um nome existente, mas não no namespace corrente? Vamos olhar para a primeira situação, se uma função 'chama' por uma variável chamada X e se existe uma variável com esse nome dentro da função (local scope) então essa será a variável utilizada pelo Python. E da responsabilidade do programador/a evitar conflitos entre nomes por forma que uma variável de local scope e uma outra de module scope ambas com o mesmo nome, não sejam ambas usadas na mesma função - porque se assim for a de local scope é que será usada.

De uma forma geral deves minimizar o uso de 'global statement' será mais fácil usares a variável como um dos parâmetros e depois obte-la já modificada.

# variáveis dentro de um módulo
W = 5
Y = 3
 
#os parâmetros utilizados também estão dentro de uma scope
#o X fica colocado numa scope local:
def spam(X):
    
   #dizer a função para não criar o seu próprio W procurar a nível do módulo
   global W
   
   Z = X*2 # uma nova variável Z é criada na scope local 
   W = X+5 # usa o módulo W criado um pouco mais acima

   if Z > W:
      # imprime é um nome que faz para da 'builtin-scope' 
      print "2 x X é maior que X + 5"
      return Z
   else:
      return Y # como não existe nenhuma variável dentro da função que se chame Y usa-se a variável do módulo

Bom o que acontece quendo importamos um módulo como o sys é qeu tormanos o nome sys disponivél de uma forma local, permintindo-nos aceder aos nomes dentro do módulo sys desta forma:

from sys import exit

assim apenas trazemos o exit para o local namespace. Mas quando fazemos isto, significa que não podemos usar o nome sys para mais nada, nem sequer variáveis..

No BASIC

No BASIC temos o processamento exactamente oposto ao Python, porque aqui todas as variáveis são globais por default (para haver compatibilidade com o BASIC mais antigo), mas o programador tem a permissão de criar variáveis locais, mesmo dentro das funções..

Tcl

Pelo menos até a data, ainda não são conhecidos ferramentas para controlar o namespace no Tcl. Possivelmente pela forma única como o interprete do Tcl funciona. De qualquer das maneiras, aqui as variáveis parecem ser locais, para os objectos que estiverem próximos - os nomes dentro dos ficheiros, são visíveis apenas aos elementos dentro do ficheiro, os nomes dentro das funções são visíveis apenas os elementos que compõem a função. Para comunicar por entre os namespaces terás que passar os valores como se fossem parâmetros.


Anterior  Próxima  Índice


Em caso que tenhas alguma dúvida ou queiras comentar esta página envia-me um e-mail para: babyboy@oninet.pt