¿Qué Son Los Espacios De Nombres De Python (Y Por Qué Se Necesitan?)
Los conflictos de nombres ocurren todo el tiempo en la vida real. Por ejemplo, cada escuela a la que fui tenía al menos dos estudiantes en mi clase que compartían el mismo nombre de pila. Si alguien entrara a la clase y preguntara por el estudiante X, preguntaríamos con entusiasmo, » ¿De cuál estás hablando? Hay dos estudiantes llamados X. » Después de eso, la persona que pregunta nos daría un apellido, y le presentaríamos a la X correcta.
Toda esta confusión y el proceso de determinar la persona exacta de la que estamos hablando buscando otra información además de un nombre se podría evitar si todos tuvieran un nombre único. Esto no es un problema en una clase de 30 estudiantes. Sin embargo, será cada vez más difícil encontrar un nombre único, significativo y fácil de recordar para cada niño en una escuela, pueblo, ciudad, país o en todo el mundo. Otro problema al proporcionar a cada niño un nombre único es que el proceso de determinar si alguien más también ha nombrado a su hijo Macey, Maci o Macie podría ser muy agotador.
Un conflicto muy similar también puede surgir en la programación. Cuando está escribiendo un programa de solo 30 líneas sin dependencias externas, es muy fácil dar nombres únicos y significativos a todas sus variables. El problema surge cuando hay miles de líneas en un programa y también ha cargado algunos módulos externos. En este tutorial, aprenderá sobre los espacios de nombres, su importancia y la resolución de alcance en Python.
¿Qué Son Los Espacios de Nombres?
Un espacio de nombres es básicamente un sistema para asegurarse de que todos los nombres de un programa sean únicos y se puedan usar sin ningún conflicto. Es posible que ya sepas que todo en cadenas, listas, funciones, etc. similares a Python.—es un objeto. Otro hecho interesante es que Python implementa espacios de nombres como diccionarios. Hay una asignación de nombre a objeto, con los nombres como claves y los objetos como valores. Varios espacios de nombres pueden usar el mismo nombre y asignarlo a un objeto diferente. Estos son algunos ejemplos de espacios de nombres:
- Espacio de nombres local: Este espacio de nombres incluye nombres locales dentro de una función. Este espacio de nombres se crea cuando se llama a una función, y solo dura hasta que la función regrese.
- Espacio de nombres global: Este espacio de nombres incluye nombres de varios módulos importados que está utilizando en un proyecto. Se crea cuando el módulo se incluye en el proyecto, y dura hasta que finaliza el script.
- Espacio de nombres integrado: Este espacio de nombres incluye funciones integradas y nombres de excepción integrados.
En la serie Mathematical Modules in Python de Envato Tuts+, escribí sobre funciones matemáticas útiles disponibles en diferentes módulos. Por ejemplo, las matemáticas y cmath módulos tienen un montón de funciones que son comunes a ambos, como log10()
acos()
cos()
exp()
, etc. Si está utilizando ambos módulos en el mismo programa, la única forma de usar estas funciones de forma inequívoca es ponerles un prefijo con el nombre del módulo, como math.log10()
y cmath.log10()
.
¿Qué Es Scope?
Los espacios de nombres nos ayudan a identificar de forma única todos los nombres dentro de un programa. Sin embargo, esto no implica que podamos usar un nombre de variable en cualquier lugar que queramos. Un nombre también tiene un ámbito que define las partes del programa donde se puede usar ese nombre sin usar ningún prefijo. Al igual que los espacios de nombres, también hay varios ámbitos en un programa. Aquí hay una lista de algunos ámbitos que pueden existir durante la ejecución de un programa.
- Un ámbito local, que es el ámbito más interno que contiene una lista de nombres locales disponibles en la función actual.
- Un ámbito de todas las funciones que encierran. La búsqueda de un nombre comienza desde el ámbito de inclusión más cercano y se mueve hacia el exterior.
- Un ámbito de nivel de módulo que contiene todos los nombres globales del módulo actual.
- El ámbito más externo que contiene una lista de todos los nombres incorporados. Este ámbito se busca por última vez para encontrar el nombre al que hizo referencia.
En las próximas secciones de este tutorial, usaremos ampliamente la función dir() de Python integrada para devolver una lista de nombres en el ámbito local actual. Esto le ayudará a entender el concepto de espacios de nombres y alcance con mayor claridad.
Resolución de alcance
Como mencioné en la sección anterior, la búsqueda de un nombre dado comienza desde la función más interna y luego se mueve más y más alto hasta que el programa puede asignar ese nombre a un objeto. Cuando no se encuentra dicho nombre en ninguno de los espacios de nombres, el programa genera una excepción de error de nombre.
Antes de comenzar, intente escribir dir()
en IDE INACTIVO o en cualquier otro IDE de Python.
dir()#
Veamos la salida de la función dir()
después de definir una variable y una función.
a_num = 10dir()# def some_func(): b_num = 11 print(dir()) some_func()# dir()#
La función dir()
solo muestra la lista de nombres dentro del ámbito actual. Es por eso que dentro del alcance de some_func()
, solo hay un nombre llamado b_num
. Llamar a dir()
después de definir some_func()
lo agrega a la lista de nombres disponibles en el espacio de nombres global.
Ahora, veamos la lista de nombres dentro de algunas funciones anidadas. El código de este bloque continúa desde el bloque anterior.
El código anterior define dos variables y una función dentro del ámbito de outer_func()
. Dentro de inner_func()
, la función dir()
solo imprime el nombre d_num
. Esto parece justo, ya que d_num
es la única variable definida allí.
A menos que se especifique explícitamente mediante global
, reasignar un nombre global dentro de un espacio de nombres local crea una nueva variable local con el mismo nombre. Esto es evidente en el siguiente código.
en el Interior tanto en el outer_func()
y inner_func()
a_num
ha sido declarado como una variable global. Solo estamos estableciendo un valor diferente para la misma variable global. Esta es la razón por la que el valor de a_num
en todas las ubicaciones es 20. Por otro lado, cada función crea su propia variable b_num
con un ámbito local, y la función print()
imprime el valor de esta variable de ámbito local.
Importar correctamente Módulos
Es muy común importar módulos externos en sus proyectos para acelerar el desarrollo. Hay tres formas diferentes de importar módulos. En esta sección, aprenderá sobre todos estos métodos, discutiendo sus pros y contras en detalle.
-
from module import *
: Este método de importar un módulo importa todos los nombres del módulo dado directamente en el espacio de nombres actual. Es posible que se sienta tentado a usar este método porque le permite usar una función directamente sin agregar el nombre del módulo como prefijo. Sin embargo, es muy propenso a errores, y también pierde la capacidad de saber qué módulo importó realmente esa función. Aquí hay un ejemplo de cómo usar este método:
Si está familiarizado con los módulos math y cmath, ya sabe que hay algunos nombres comunes que se definen en ambos módulos, pero que se aplican a números reales y complejos respectivamente.
Dado que hemos importado el módulo cmath después del módulo math, sobrescribe las definiciones de funciones de estas funciones comunes desde el módulo math. Esta es la razón por la que el primer log10(125)
devuelve un número real y el segundo log10(125)
devuelve un número complejo. No hay forma de usar la función log10()
del módulo de matemáticas ahora. Incluso si ha intentado escribir math.log10(125)
, obtendrá una excepción de error de nombre porque math
no existe en realidad en el espacio de nombres.
La conclusión es que no debe usar esta forma de importar funciones de diferentes módulos solo para guardar algunas pulsaciones de teclas.
-
from module import nameA, nameB
: Si sabe que solo va a usar uno o dos nombres de un módulo, puede importarlos directamente utilizando este método. De esta manera, puede escribir el código de forma más concisa, manteniendo al mínimo la contaminación del espacio de nombres. Sin embargo, tenga en cuenta que aún no puede usar ningún otro nombre del módulo usandomodule.nameZ
. Cualquier función que tenga el mismo nombre en su programa también sobrescribirá la definición de esa función importada desde el módulo. Esto hará que la función importada sea inutilizable. Aquí es un ejemplo del uso de este método:
dir()# from math import log2, log10dir()# log10(125)# 2.0969100130080562
-
import module
: Esta es la más segura y recomendable forma de importar un módulo. El único inconveniente es que tendrás que anteponer el nombre del módulo a todos los nombres que vas a usar en el programa. Sin embargo, podrá evitar la contaminación del espacio de nombres y también definir funciones cuyos nombres coincidan con el nombre de las funciones del módulo.
dir()# import mathdir()# math.log10(125)# 2.0969100130080562
Pensamientos finales
Espero que este tutorial le haya ayudado a comprender los espacios de nombres y su importancia. Ahora debería poder determinar el alcance de los diferentes nombres en un programa y evitar posibles escollos.
Además, no dude en ver lo que tenemos disponible para la venta y para estudiar en el mercado, y no dude en hacer cualquier pregunta y proporcionar sus valiosos comentarios utilizando el feed a continuación.
La sección final del artículo discutió las diferentes formas de importar módulos en Python y los pros y los contras de cada uno de ellos. Si tiene alguna pregunta relacionada con este tema, hágamelo saber en los comentarios.
Aprende Python
Aprende Python con nuestra completa guía tutorial de python, tanto si acabas de empezar como si eres un codificador experimentado que busca aprender nuevas habilidades.