O Que São Os Namespaces Python (E Por Que Eles São Necessários?)
conflitos de nomes acontecem o tempo todo na vida real. Por exemplo, todas as escolas que frequentei tinham pelo menos dois alunos da minha turma que partilhavam o mesmo primeiro nome. Se alguém viesse à aula e pedisse um estudante X, nós perguntaríamos com entusiasmo: “de qual você está falando? Há dois estudantes chamados X.” Depois disso, a pessoa inquiridora nos daria um sobrenome, e nós o apresentaríamos ao X. direito.
toda esta confusão e o processo de determinar a pessoa exata de que estamos falando, procurando outras informações além de um primeiro nome, poderiam ser evitados se todos tivessem um nome único. Isto não é um problema numa classe de 30 alunos. No entanto, tornar-se-á cada vez mais difícil criar um nome único, significativo e fácil de lembrar para cada criança em uma escola, Cidade, Cidade, país, ou todo o mundo. Outra questão em fornecer a cada criança um nome único é que o processo de determinar se alguém também nomeou seu filho Macey, Maci ou Macie poderia ser muito cansativo.um conflito muito semelhante também pode surgir na programação. Quando você está escrevendo um programa de apenas 30 linhas sem dependências externas, é muito fácil dar nomes únicos e significativos para todas as suas variáveis. O problema surge quando há milhares de linhas em um programa e você carregou alguns módulos externos também. Neste tutorial, você vai aprender sobre os espaços de nomes, sua importância e resolução de escopo em Python.
o que são espaços de nomes?
um espaço de nomes é basicamente um sistema para se certificar de que todos os nomes de um programa são únicos e podem ser usados sem qualquer conflito. Você já deve saber que tudo em strings, listas, funções, etc.- é um objecto. Outro fato interessante é que Python implementa espaços de nomes como dicionários. Há um mapeamento nome-a-objeto, com os nomes como chaves e os objetos como valores. Múltiplos espaços de nomes podem usar o mesmo nome e mapeá-lo para um objeto diferente. Aqui estão alguns exemplos de espaços de nomes:
- espaço de nomes Local: Este espaço de nomes inclui nomes locais dentro de uma função. Este espaço de nomes é criado quando uma função é chamada, e só dura até que a função retorne.
- espaço de nomes Global: este espaço de nomes inclui nomes de vários módulos importados que está a usar num projecto. Ele é criado quando o módulo é incluído no projeto, e dura até o script terminar.
- Namespace embutido: este namespace inclui funções embutidas e nomes de excepções embutidos.
nos Módulos Matemáticos da série Python sobre Envato Tuts+, eu escrevi sobre funções matemáticas úteis disponíveis em diferentes módulos. Por exemplo, a matemática e cmath módulos tem um monte de funções que são comuns a ambos, como log10()
acos()
cos()
exp()
, etc. Se você estiver usando os dois módulos no mesmo programa, a única forma de utilizar estas funções de forma inequívoca é prefixo-los com o nome do módulo, como math.log10()
e cmath.log10()
.o que é o âmbito?os espaços de nomes
ajudam-nos a identificar todos os nomes dentro de um programa. No entanto, isso não implica que podemos usar um nome de variável em qualquer lugar que quisermos. Um nome também tem um escopo que define as partes do programa onde você poderia usar esse nome sem usar qualquer prefixo. Assim como os espaços de nomes, também existem múltiplos âmbitos em um programa. Aqui está uma lista de alguns âmbitos que podem existir durante a execução de um programa.
- um escopo local, que é o escopo mais profundo que contém uma lista de nomes locais disponíveis na função atual.
- a scope of all the enclosing functions. A busca por um nome começa a partir do escopo envolvente mais próximo e se move para o exterior.
- um âmbito de nível de módulos que contém todos os nomes globais do módulo actual.
- O âmbito mais externo que contém uma lista de todos os nomes incorporados. Este escopo é procurado por último para encontrar o nome que referenciou.
nas secções seguintes deste tutorial, iremos usar extensivamente a função dir() incorporada em Python para devolver uma lista de nomes no âmbito local actual. Isso irá ajudá-lo a entender o conceito de espaços de nomes e escopo mais claramente.
resolução de escopo
Como mencionei na seção anterior, a busca por um determinado nome começa a partir da função mais interna e, em seguida, se move mais e mais alto até que o programa pode mapear esse nome para um objeto. Quando esse nome não é encontrado em nenhum dos espaços de nomes, o programa levanta uma exceção de NameError.
Antes de começarmos, tente digitar dir()
em IDLE ou qualquer outro IDE Python.
dir()#
Let’s see the output of the dir()
function after defining a variable and a function.
a_num = 10dir()# def some_func(): b_num = 11 print(dir()) some_func()# dir()#
a função dir()
apenas produz a lista de nomes dentro do âmbito actual. É por isso que dentro do escopo de some_func()
, há apenas um nome chamado b_num
. Calling dir()
after definingsome_func()
adds it to the list of namespace available in the global namespace.
Agora, vamos ver a lista de nomes dentro de algumas funções aninhadas. O código neste bloco continua do bloco anterior.
o código acima define duas variáveis e uma função dentro do escopo de outer_func()
. Inside inner_func()
, the dir()
function only prints the named_num
. Isto parece justo pois d_num
é a única variável definida lá.
a Menos que explicitamente especificado usando global
, associar um nome global dentro de um espaço de nomes local cria uma nova variável local com o mesmo nome. Isto é evidente no seguinte código.
Dentro de outer_func()
e inner_func()
a_num
foi declarado como uma variável global. Estamos apenas a definir um valor diferente para a mesma variável global. Esta é a razão pela qual o valor de a_num
em todos os locais é 20. Por outro lado, cada função cria o seu próprio b_num
variável com um escopo local, e o print()
função imprime o valor da variável do escopo local.é muito comum importar módulos externos em seus projetos para acelerar o desenvolvimento. Existem três maneiras diferentes de importar módulos. Nesta seção, você vai aprender sobre todos esses métodos, discutindo seus prós e contras em detalhes.
-
from module import *
: Este método de importação de um módulo importa todos os nomes do módulo indicado directamente no seu espaço de nomes actual. Você pode ser tentado a usar este método porque ele permite que você use uma função diretamente sem adicionar o nome do módulo como um prefixo. No entanto, é muito propenso a erros, e você também perde a capacidade de dizer qual módulo realmente importou essa função. Aqui está um exemplo de usar este método:
Se estiver familiarizado com os módulos math e cmath, você já sabe que existem alguns nomes comuns que são definidos em ambos os módulos, mas se aplicam aos números reais e complexos, respectivamente.
Uma vez que importamos o módulo cmath após o módulo matemático, ele substitui as definições de função destas funções comuns do módulo matemático. É por isso que o primeiro log10(125)
devolve um número real e o segundo log10(125)
devolve um número complexo. Não há nenhuma maneira para você usar a função log10()
do módulo matemático agora. Mesmo que tenha tentado escrever math.log10(125)
, irá obter uma excepção de NameError porque math
não existe de facto no espaço de nomes.
a conclusão é que você não deve usar esta forma de importar funções de diferentes módulos apenas para salvar algumas teclas.
-
from module import nameA, nameB
: se souber que só vai usar um ou dois nomes de um módulo, poderá importá-los directamente com este método. Desta forma, você pode escrever o código de forma mais concisa, mantendo a poluição do espaço de nomes a um mínimo. No entanto, tenha em mente que você ainda não pode usar qualquer outro nome do módulo usandomodule.nameZ
. Qualquer função que tenha o mesmo nome em seu programa também irá sobrepor a definição dessa função importada do módulo. Isto tornará a função importada inutilizável. Aqui está um exemplo de usar este método:
dir()# from math import log2, log10dir()# log10(125)# 2.0969100130080562
-
import module
: esta é a maneira mais segura e recomendada de importar um módulo. A única desvantagem é que você terá que prefixar o nome do módulo para todos os nomes que você vai usar no programa. No entanto, você será capaz de evitar a poluição do espaço de nomes e também definir funções cujos nomes coincidem com o nome das funções do módulo.
dir()# import mathdir()# math.log10(125)# 2.0969100130080562
Pensamentos finais
espero que este tutorial o tenha ajudado a compreender os espaços de nomes e a sua importância. Você deve agora ser capaz de determinar o escopo de nomes diferentes em um programa e evitar potenciais armadilhas. além disso, não hesite em ver o que temos disponível para venda e para estudo no mercado, e não hesite em fazer quaisquer perguntas e fornecer o seu valioso feedback usando o feed abaixo.
a seção final do artigo discutiu diferentes maneiras de importar módulos em Python e os prós e contras de cada um deles. Se você tiver alguma dúvida relacionada a este tópico, por favor me avise nos comentários.
aprenda Python
aprenda Python com o nosso Guia tutorial python completo, quer esteja apenas a começar ou seja um programador experiente que procura aprender novas competências.