Una revisión de los conceptos básicos de los módulos

PythonPythonBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás los conceptos básicos de los módulos de Python. Los módulos son archivos de Python con definiciones de funciones, clases y variables que se pueden utilizar en otros programas de Python. Ayudan a organizar el código en unidades lógicas y mejoran la reutilización.

Al final de este laboratorio, entenderás cómo crear tus propios módulos, importarlos de varias maneras y comprender los comportamientos importantes de carga de módulos que afectan tu código.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/ModulesandPackagesGroup(["Modules and Packages"]) python(("Python")) -.-> python/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) python/BasicConceptsGroup -.-> python/variables_data_types("Variables and Data Types") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/ModulesandPackagesGroup -.-> python/importing_modules("Importing Modules") python/ModulesandPackagesGroup -.-> python/creating_modules("Creating Modules") python/ObjectOrientedProgrammingGroup -.-> python/classes_objects("Classes and Objects") subgraph Lab Skills python/variables_data_types -.-> lab-132528{{"Una revisión de los conceptos básicos de los módulos"}} python/function_definition -.-> lab-132528{{"Una revisión de los conceptos básicos de los módulos"}} python/importing_modules -.-> lab-132528{{"Una revisión de los conceptos básicos de los módulos"}} python/creating_modules -.-> lab-132528{{"Una revisión de los conceptos básicos de los módulos"}} python/classes_objects -.-> lab-132528{{"Una revisión de los conceptos básicos de los módulos"}} end

Creación de un módulo simple

Comencemos nuestro viaje por los módulos de Python creando uno simple. En Python, un módulo es esencialmente un archivo con extensión .py que contiene código de Python. Piénsalo como un contenedor donde puedes agrupar funciones, clases y variables relacionadas. Esto hace que tu código esté más organizado y sea más fácil de gestionar, especialmente a medida que tus proyectos aumentan de tamaño.

  1. Primero, abre el WebIDE. Una vez abierto, necesitarás crear un nuevo archivo. Para hacer esto, haz clic en "File" en la barra de menú y luego selecciona "New File". Nombrar este nuevo archivo simplemod.py y guárdalo en el directorio /home/labex/project. Este es el directorio donde guardaremos todos los archivos relacionados con este experimento.

  2. Ahora, agreguemos algo de código a nuestro recién creado archivo simplemod.py. El código siguiente define algunos elementos básicos que comúnmente encontrarás en un módulo de Python.

## simplemod.py

x = 42        ## Una variable global

## Una función simple
def foo():
    print('x is', x)

## Una clase simple
class Spam:
    def yow(self):
        print('Yow!')

## Una declaración de script
print('Loaded simplemod')

En este código:

  • x = 42 crea una variable global llamada x y le asigna el valor 42. Las variables globales se pueden acceder desde cualquier lugar dentro del módulo.
  • La función foo() se define para imprimir el valor de la variable global x. Las funciones son bloques de código reutilizables que realizan una tarea específica.
  • La clase Spam es un modelo para crear objetos. Tiene un método llamado yow(), que simplemente imprime la cadena 'Yow!'. Los métodos son funciones que pertenecen a una clase.
  • La declaración print('Loaded simplemod') es una declaración de script. Se ejecutará tan pronto como se cargue el módulo, lo que nos ayuda a confirmar que el módulo se ha cargado correctamente.
  1. Después de agregar el código, guarda el archivo. Puedes hacer esto presionando Ctrl+S en tu teclado o seleccionando "File" > "Save" del menú. Guardar el archivo asegura que todos los cambios que hayas realizado se conserven.

Echemos un vistazo más detallado a lo que contiene este módulo:

  • Una variable global x con el valor 42. Esta variable se puede usar en todo el módulo e incluso acceder desde otros módulos si se importa correctamente.
  • Una función foo() que imprime el valor de x. Las funciones son útiles para realizar tareas repetitivas sin tener que escribir el mismo código varias veces.
  • Una clase Spam con un método yow(). Las clases y los métodos son conceptos fundamentales en la programación orientada a objetos, que te permite crear estructuras de datos y comportamientos complejos.
  • Una declaración print que se ejecuta cuando se carga el módulo. Esta declaración sirve como indicador visual de que el módulo se ha cargado correctamente en el entorno de Python.

La declaración print al final nos ayudará a observar cuándo se carga el módulo, lo cual es importante para la depuración y la comprensión de cómo funcionan los módulos en Python.

✨ Revisar Solución y Practicar

Importación y uso de módulos

Ahora que hemos creado un módulo, es hora de entender cómo importarlo y utilizar sus componentes. En Python, un módulo es un archivo que contiene definiciones y declaraciones de Python. Cuando importas un módulo, obtienes acceso a todas las funciones, clases y variables definidas en él. Esto te permite reutilizar código y organizar tus programas de manera más efectiva.

  1. Primero, necesitamos abrir una nueva terminal en el WebIDE. Esta terminal servirá como nuestro espacio de trabajo donde podemos ejecutar comandos de Python. Para abrir una nueva terminal, haz clic en "Terminal" > "New Terminal".

  2. Una vez abierta la terminal, necesitamos iniciar el intérprete de Python. El intérprete de Python es un programa que lee y ejecuta código de Python. Para iniciarlo, escribe el siguiente comando en la terminal y presiona Enter:

python3
  1. Ahora que el intérprete de Python está en funcionamiento, podemos importar nuestro módulo. En Python, usamos la declaración import para traer un módulo a nuestro programa actual. Escribe el siguiente comando en el intérprete de Python:
>>> import simplemod
Loaded simplemod

Notarás que aparece "Loaded simplemod" en la salida. Esto se debe a que la declaración print en nuestro módulo simplemod se ejecuta cuando el módulo se carga. Cuando Python importa un módulo, ejecuta todo el código de nivel superior en ese módulo, incluyendo cualquier declaración print.

  1. Después de importar el módulo, podemos acceder a sus componentes utilizando la notación de punto. La notación de punto es una forma de acceder a los atributos (variables y funciones) de un objeto en Python. En este caso, el módulo es un objeto, y sus funciones, variables y clases son sus atributos. Aquí hay algunos ejemplos de cómo acceder a diferentes componentes del módulo simplemod:
>>> simplemod.x
42
>>> simplemod.foo()
x is 42
>>> spam_instance = simplemod.Spam()
>>> spam_instance.yow()
Yow!

En la primera línea, accedemos a la variable x definida en el módulo simplemod. En la segunda línea, llamamos a la función foo del módulo simplemod. En la tercera y cuarta línea, creamos una instancia de la clase Spam definida en el módulo simplemod y llamamos a su método yow.

  1. A veces, puedes encontrar un ImportError cuando intentas importar un módulo. Este error ocurre cuando Python no puede encontrar el módulo que estás intentando importar. Para averiguar dónde Python está buscando los módulos, puedes examinar la variable sys.path. La variable sys.path es una lista de directorios que Python busca cuando está buscando módulos. Escribe los siguientes comandos en el intérprete de Python:
>>> import sys
>>> sys.path
['', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/usr/local/lib/python3.10/dist-packages', '/usr/lib/python3/dist-packages']

El primer elemento de la lista (la cadena vacía) representa el directorio de trabajo actual. Aquí es donde Python busca el archivo simplemod.py. Si tu módulo no está en uno de los directorios enumerados en sys.path, Python no podrá encontrarlo y obtendrás un ImportError. Asegúrate de que tu archivo simplemod.py esté en el directorio de trabajo actual o en uno de los otros directorios de sys.path.

Comprendiendo el comportamiento de carga de módulos

En Python, la forma en que se cargan los módulos tiene algunas características interesantes. En este paso, exploraremos estos comportamientos para entender cómo Python gestiona la carga de módulos.

  1. Primero, veamos qué sucede cuando intentamos importar un módulo nuevamente dentro de la misma sesión del intérprete de Python. Cuando inicias un intérprete de Python, es como abrir un espacio de trabajo donde puedes ejecutar código de Python. Una vez que has importado un módulo, importarlo nuevamente podría parecer que recargaría el módulo, pero no es así.
>>> import simplemod

Observa que esta vez no ves la salida "Loaded simplemod". Esto se debe a que Python solo carga un módulo una vez por sesión del intérprete. Las declaraciones import posteriores no recargan el módulo. Python recuerda que ya ha cargado el módulo, por lo que no pasa por el proceso de cargarlo nuevamente.

  1. Después de importar un módulo, puedes modificar las variables dentro de él. Un módulo en Python es como un contenedor que almacena variables, funciones y clases. Una vez que has importado un módulo, puedes acceder y cambiar sus variables al igual que con cualquier otro objeto de Python.
>>> simplemod.x
42
>>> simplemod.x = 13
>>> simplemod.x
13
>>> simplemod.foo()
x is 13

Aquí, primero comprobamos el valor de la variable x en el módulo simplemod, que inicialmente es 42. Luego cambiamos su valor a 13 y verificamos que se haya realizado el cambio. Cuando llamamos a la función foo en el módulo, se refleja el nuevo valor de x.

  1. Importar el módulo nuevamente no restablece los cambios que hicimos en sus variables. Incluso si intentamos importar el módulo una vez más, Python no lo recarga, por lo que los cambios que hicimos en sus variables se mantienen.
>>> import simplemod
>>> simplemod.x
13
  1. Si quieres forzar la recarga de un módulo, necesitas usar la función importlib.reload(). A veces, es posible que hayas realizado cambios en el código del módulo y quieras ver que esos cambios surtan efecto inmediatamente. La función importlib.reload() te permite hacer precisamente eso.
>>> import importlib
>>> importlib.reload(simplemod)
Loaded simplemod
<module 'simplemod' from 'simplemod.py'>
>>> simplemod.x
42
>>> simplemod.foo()
x is 42

El módulo se ha recargado y el valor de x se ha restablecido a 42. Esto muestra que el módulo se ha cargado nuevamente desde su código fuente y todas las variables se han inicializado como estaban originalmente.

  1. Python lleva un registro de todos los módulos cargados en el diccionario sys.modules. Este diccionario actúa como un registro donde Python almacena información sobre todos los módulos que se han cargado durante la sesión actual del intérprete.
>>> 'simplemod' in sys.modules
True
>>> sys.modules['simplemod']
<module 'simplemod' from 'simplemod.py'>

Al comprobar si el nombre de un módulo está en el diccionario sys.modules, puedes ver si el módulo se ha cargado. Y al acceder al diccionario con el nombre del módulo como clave, puedes obtener información sobre el módulo.

  1. Puedes eliminar un módulo de este diccionario para forzar a Python a recargarlo en la próxima importación. Si eliminas un módulo del diccionario sys.modules, Python olvida que ya ha cargado el módulo. Entonces, la próxima vez que intentes importarlo, Python lo cargará nuevamente desde su código fuente.
>>> del sys.modules['simplemod']
>>> import simplemod
Loaded simplemod
>>> simplemod.x
42

El módulo se cargó nuevamente porque se eliminó de sys.modules. Esta es otra forma de asegurarte de que estás trabajando con la última versión del código de un módulo.

Utilizando la sintaxis from module import

En Python, hay varias formas de importar componentes de módulos. Una de estas formas es la sintaxis from module import, que exploraremos en esta sección.

Cuando importas componentes de un módulo, a menudo es una buena idea comenzar con un entorno limpio. Esto asegura que no haya variables o configuraciones residuales de interacciones anteriores que puedan interferir con nuestro experimento actual.

  1. Reinicia el intérprete de Python para obtener un estado limpio:
>>> exit()

Este comando sale de la sesión actual del intérprete de Python. Después de salir, iniciaremos una nueva sesión para garantizar un entorno nuevo.

python3

Este comando de bash inicia una nueva sesión del intérprete de Python 3. Ahora que tenemos un entorno de Python limpio, podemos comenzar a importar componentes de un módulo.

  1. Importa componentes específicos de un módulo utilizando la sintaxis from module import:
>>> from simplemod import foo
Loaded simplemod
>>> foo()
x is 42

Aquí, estamos utilizando la declaración from simplemod import foo para importar solo la función foo del módulo simplemod. Observa que aunque solo pedimos la función foo, se cargó el módulo simplemod completo. Esto se indica por la salida "Loaded simplemod". La razón de esto es que Python necesita cargar todo el módulo para acceder a la función foo.

  1. Cuando se utiliza from module import, no se puede acceder al módulo en sí:
>>> simplemod.foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'simplemod' is not defined

Cuando utilizamos la sintaxis from module import, solo estamos trayendo los componentes especificados directamente a nuestro espacio de nombres. El nombre del módulo en sí no se importa. Entonces, cuando intentamos acceder a simplemod.foo(), Python no reconoce simplemod porque no se importó de esa manera.

  1. Puedes importar múltiples componentes a la vez:
>>> from simplemod import x, foo
>>> x
42
>>> foo()
x is 42

La sintaxis from module import nos permite importar múltiples componentes de un módulo en una sola declaración. Aquí, estamos importando tanto la variable x como la función foo del módulo simplemod. Después de importarlos, podemos acceder directamente a estos componentes en nuestro código.

  1. Cuando importas una variable de un módulo, estás creando una nueva referencia al objeto, no un enlace a la variable en el módulo:
>>> x = 13  ## Change the local variable x
>>> x
13
>>> foo()
x is 42  ## The function still uses the module's x, not your local x

Cuando importamos una variable de un módulo, esencialmente estamos creando una nueva referencia al mismo objeto en nuestro espacio de nombres local. Entonces, cuando cambiamos la variable local x a 13, no afecta a la variable x dentro del módulo simplemod. La función foo() sigue refiriéndose a la variable x del módulo, que es 42. Comprender este concepto es crucial para evitar confusiones en tu código.

Explorando las limitaciones de la recarga de módulos

La recarga de módulos es una función útil en Python, pero tiene algunas limitaciones, especialmente cuando se trata de clases. En esta sección, exploraremos estas limitaciones paso a paso. Comprender estas limitaciones es crucial tanto para entornos de desarrollo como de producción.

  1. Reinicia el intérprete de Python:
    Primero, necesitamos reiniciar el intérprete de Python. Este paso es importante porque asegura que comenzamos con un entorno limpio. Cuando reinicias el intérprete, se borran todos los módulos y variables importados previamente. Para salir del intérprete de Python actual, utiliza el comando exit(). Luego, inicia una nueva sesión del intérprete de Python utilizando el comando python3 en la terminal.
>>> exit()
python3
  1. Importa el módulo y crea una instancia de la clase Spam:
    Ahora que tenemos una nueva sesión del intérprete de Python, importaremos el módulo simplemod. Importar un módulo nos permite utilizar las clases, funciones y variables definidas en ese módulo. Después de importar el módulo, crearemos una instancia de la clase Spam y llamaremos a su método yow(). Esto nos ayudará a ver el comportamiento inicial de la clase.
>>> import simplemod
Loaded simplemod
>>> s = simplemod.Spam()
>>> s.yow()
Yow!
  1. Ahora modifiquemos la clase Spam en nuestro módulo. Sal del intérprete de Python:
    A continuación, vamos a hacer cambios en la clase Spam del módulo simplemod. Antes de hacerlo, necesitamos salir del intérprete de Python. Esto se debe a que queremos hacer cambios en el código fuente del módulo y luego ver cómo esos cambios afectan el comportamiento de la clase.
>>> exit()
  1. Abre el archivo simplemod.py en el WebIDE y modifica la clase Spam:
    Abre el archivo simplemod.py en el WebIDE. Aquí es donde se encuentra el código fuente del módulo simplemod. Modificaremos el método yow() de la clase Spam para que imprima un mensaje diferente. Este cambio nos ayudará a observar cómo cambia el comportamiento de la clase después de recargar el módulo.
## simplemod.py
## ... (deja el resto del archivo sin cambios)

class Spam:
    def yow(self):
        print('More Yow!')  ## Changed from 'Yow!'
  1. Guarda el archivo y regresa a la terminal. Inicia el intérprete de Python y crea una nueva instancia:
    Después de hacer los cambios en el archivo simplemod.py, guárdalo. Luego, regresa a la terminal e inicia una nueva sesión del intérprete de Python. Importa el módulo simplemod nuevamente y crea una nueva instancia de la clase Spam. Llama al método yow() de la nueva instancia para ver el comportamiento actualizado.
python3
>>> import simplemod
Loaded simplemod
>>> t = simplemod.Spam()
>>> t.yow()
More Yow!
  1. Ahora demostremos lo que sucede con la recarga:
    Para ver cómo funciona la recarga de módulos, utilizaremos la función importlib.reload(). Esta función nos permite recargar un módulo previamente importado. Después de recargar el módulo, veremos si los cambios que hicimos en la clase Spam se reflejan.
>>> import importlib
>>> importlib.reload(simplemod)
Loaded simplemod
<module 'simplemod' from 'simplemod.py'>
  1. Sal de Python, modifica el archivo nuevamente y luego prueba ambas instancias:
    Sal del intérprete de Python una vez más. Luego, haz otro cambio en la clase Spam del archivo simplemod.py. Después de eso, probaremos tanto la instancia antigua como la nueva de la clase Spam para ver cómo se comportan.
>>> exit()
  1. Actualiza el archivo simplemod.py:
    Abre el archivo simplemod.py nuevamente y modifica el método yow() de la clase Spam para que imprima un mensaje diferente. Este cambio nos ayudará a comprender mejor las limitaciones de la recarga de módulos.
## simplemod.py
## ... (deja el resto del archivo sin cambios)

class Spam:
    def yow(self):
        print('Even More Yow!')  ## Changed again
  1. Guarda el archivo y regresa a la terminal:
    Guarda los cambios en el archivo simplemod.py y regresa a la terminal. Inicia una nueva sesión del intérprete de Python, importa el módulo simplemod y crea una nueva instancia de la clase Spam. Llama al método yow() de la nueva instancia para ver el comportamiento actualizado.
python3
>>> import simplemod
Loaded simplemod
>>> s = simplemod.Spam()
>>> s.yow()
Even More Yow!

>>> ## Exit without closing Python, edit the file
  1. Sin cerrar Python, abre simplemod.py en el WebIDE y cámbialo:
    Sin cerrar el intérprete de Python, abre el archivo simplemod.py en el WebIDE y haz otro cambio en el método yow() de la clase Spam. Esto nos ayudará a ver cómo cambia el comportamiento de las instancias existentes y nuevas después de recargar el módulo.
## simplemod.py
## ... (deja el resto del archivo sin cambios)

class Spam:
    def yow(self):
        print('Super Yow!')  ## Changed one more time
  1. Guarda el archivo y regresa al intérprete de Python:
    Guarda los cambios en el archivo simplemod.py y regresa al intérprete de Python. Recarga el módulo simplemod utilizando la función importlib.reload(). Luego, prueba tanto la instancia antigua como la nueva de la clase Spam para ver cómo se comportan.
>>> import importlib
>>> importlib.reload(simplemod)
Loaded simplemod
<module 'simplemod' from 'simplemod.py'>

>>> ## Try the old instance
>>> s.yow()
Even More Yow!  ## Still uses the old implementation

>>> ## Create a new instance
>>> t = simplemod.Spam()
>>> t.yow()
Super Yow!  ## Uses the new implementation

Observa que la instancia antigua s sigue utilizando la implementación antigua, mientras que la nueva instancia t utiliza la nueva implementación. Esto sucede porque recargar un módulo no actualiza las instancias existentes de las clases. Cuando se crea una instancia de una clase, almacena una referencia al objeto de clase en ese momento. Recargar el módulo crea un nuevo objeto de clase, pero las instancias existentes todavía se refieren al objeto de clase antiguo.

  1. También puedes observar otros comportamientos inusuales:
    Podemos observar más las limitaciones de la recarga de módulos utilizando la función isinstance(). Esta función comprueba si un objeto es una instancia de una clase en particular. Después de recargar el módulo, veremos que la instancia antigua s ya no se considera una instancia de la nueva clase simplemod.Spam, mientras que la nueva instancia t sí lo es.
>>> isinstance(s, simplemod.Spam)
False
>>> isinstance(t, simplemod.Spam)
True

Esto indica que después de la recarga, simplemod.Spam se refiere a un objeto de clase diferente al que se utilizó para crear s.

Estas limitaciones hacen que la recarga de módulos sea útil principalmente para desarrollo y depuración, pero no se recomienda para código de producción. En un entorno de producción, es importante asegurarse de que todas las instancias de una clase utilicen la misma implementación actualizada. La recarga de módulos puede provocar un comportamiento inconsistente, que puede ser difícil de depurar y mantener.

Resumen

En este laboratorio, has aprendido los fundamentos del trabajo con módulos en Python. Has aprendido cómo crear un módulo de Python como un archivo .py con variables, funciones y clases, y cómo importar módulos utilizando la declaración import. También comprendes que Python carga los módulos solo una vez por sesión del intérprete y que puedes usar importlib.reload() para forzar la recarga.

Además, has explorado el diccionario sys.modules para realizar un seguimiento de los módulos cargados, has utilizado la sintaxis from module import para importar componentes específicos y has comprendido las limitaciones de la recarga de módulos, especialmente con clases. Estos conceptos son la base para organizar el código de Python en componentes reutilizables, lo cual es esencial para mantener la estructura del código y promover la reutilización en aplicaciones más grandes.