Importar Módulos y Paquetes en Python

PythonBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá los fundamentos de la organización y reutilización de código en Python trabajando con módulos y paquetes. Comenzaremos entendiendo qué es un módulo de Python y cómo cambia su comportamiento de ejecución dependiendo de si se ejecuta directamente o se importa.

Luego practicará las dos formas principales de incorporar código de módulos a su programa: la sentencia import para cargar un módulo completo y la sentencia from...import para cargar funciones o variables específicas. Finalmente, aprenderá a estructurar módulos relacionados en un paquete para crear un proyecto bien organizado y escalable. Toda la codificación se realizará dentro del WebIDE, utilizando archivos Python y la terminal.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 94%. Ha recibido una tasa de reseñas positivas del 97% por parte de los estudiantes.

Comprender los Módulos de Python

Un módulo en Python es simplemente un archivo que contiene código Python, el cual tiene una extensión .py. Los módulos le permiten organizar lógicamente su código, facilitando su gestión y reutilización. Las funciones, clases y variables definidas en un módulo pueden ser utilizadas en otros scripts.

En su WebIDE, verá un explorador de archivos en el lado izquierdo. El entorno del laboratorio ya ha creado un archivo llamado hello.py en el directorio ~/project.

Primero, abra hello.py para examinar su contenido. Debería contener el siguiente código:

print("This code runs on import or direct execution.")

if __name__ == "__main__":
    print("This code runs ONLY when the script is executed directly.")

El bloque if __name__ == "__main__": es una construcción especial en Python. La variable __name__ es una variable incorporada que se evalúa como el nombre del módulo actual. Cuando un script de Python se ejecuta directamente desde la línea de comandos, su __name__ se establece en la cadena "__main__". Esta sentencia if le permite escribir código que solo se ejecutará cuando el archivo se ejecute como el programa principal, y no cuando sea importado por otro módulo.

Veamos esto en acción. Abra la terminal en su WebIDE y ejecute el script hello.py directamente:

python3 hello.py

Verá la siguiente salida, ya que ambas sentencias print se ejecutan:

This code runs on import or direct execution.
This code runs ONLY when the script is executed directly.

Esto demuestra el comportamiento de un script cuando es el programa principal que se está ejecutando. En el siguiente paso, veremos qué sucede cuando lo importamos como un módulo.

Importar Módulos con la Sentencia import

La forma más común de utilizar un módulo es importarlo usando la sentencia import. Esto hace que todo el código del módulo esté disponible para su script actual.

En el explorador de archivos, encontrará un archivo vacío llamado main.py. Este será nuestro script principal para el resto del laboratorio.

Abra main.py y añada la siguiente línea para importar el módulo hello:

import hello

print("The main.py script has finished.")

Guarde el archivo. Ahora, ejecute main.py desde la terminal:

python3 main.py

Observe la salida cuidadosamente:

This code runs on import or direct execution.
The main.py script has finished.

Notará que solo se ejecutó la primera sentencia print de hello.py. El código dentro del bloque if __name__ == "__main__": fue omitido. Esto se debe a que cuando main.py importa hello, la variable __name__ dentro del contexto de hello.py se establece en "hello" (el nombre del módulo), no en "__main__". Esta característica es esencial para crear módulos reutilizables que no producen efectos secundarios no deseados al ser importados.

Ahora, trabajemos con un módulo que contiene más que solo sentencias de impresión. Abra el archivo module_a.py. Contiene una variable, una función y una clase.

PI = 3.14159

def greet(name):
 print(f"Hello, {name} from module_a!")

class Calculator:
    def add(self, x, y):
        return x + y

Modifique main.py para importar module_a y utilizar sus miembros. Para acceder a un miembro de un módulo importado, se utiliza la sintaxis nombre_del_modulo.nombre_del_miembro.

Reemplace el contenido de main.py con lo siguiente:

import module_a

## Access the PI variable
print(f"The value of PI is {module_a.PI}")

## Call the greet function
module_a.greet("LabEx")

## Create an instance of the Calculator class and use its method
calc = module_a.Calculator()
result = calc.add(5, 3)
print(f"5 + 3 = {result}")

Guarde el archivo y ejecútelo:

python3 main.py

La salida será:

The value of PI is 3.14159
Hello, LabEx from module_a!
5 + 3 = 8

Esto demuestra cómo la sentencia import carga un módulo completo, y usted accede a su contenido utilizando el nombre del módulo como prefijo.

Importar Objetos Específicos con from...import

A veces, solo necesita algunos elementos específicos de un módulo. La sentencia from...import le permite importar funciones, clases o variables específicas directamente al namespace (espacio de nombres) de su script actual. Esto significa que puede usarlas sin el prefijo nombre_del_modulo..

Modifiquemos main.py para usar este método de importación. En lugar de importar todo module_a, importaremos solo la variable PI y la función greet.

Actualice main.py con el siguiente código:

from module_a import PI, greet

## Access PI and greet directly without the module prefix
print(f"The value of PI is {PI}")
greet("World")

Guarde el archivo y ejecútelo desde la terminal:

python3 main.py

La salida será:

The value of PI is 3.14159
Hello, World from module_a!

Como puede ver, PI y greet se utilizan directamente. Sin embargo, si intenta acceder a algo que no importó, como la clase Calculator, obtendrá un error.

Inténtelo ahora. Agregue las siguientes líneas al final de main.py:

calc = Calculator()
print(calc.add(10, 20))

Ejecute el script nuevamente:

python3 main.py

Esta vez, el script fallará con un NameError (Error de Nombre):

The value of PI is 3.14159
Hello, World from module_a!
Traceback (most recent call last):
  File "/home/labex/project/main.py", line 7, in <module>
    calc = Calculator()
NameError: name 'Calculator' is not defined

Este error confirma que solo los objetos especificados en la sentencia from...import se traen al namespace actual. Este método puede hacer que su código sea más legible, pero también aumenta el riesgo de conflictos de nombres si importa objetos con el mismo nombre desde diferentes módulos.

Antes de pasar al siguiente paso, elimine las dos líneas que causaron el error de main.py.

Comprensión y Uso de Paquetes Python

A medida que los proyectos crecen, es posible que desee organizar módulos relacionados en una jerarquía de directorios única. Para esto sirven los paquetes. Un paquete es un directorio que contiene un archivo especial llamado __init__.py (que puede estar vacío). La presencia de este archivo le indica a Python que trate el directorio como un paquete.

Crearemos un paquete para alojar nuestro module_a.

Primero, cree un nuevo directorio llamado my_package en el directorio ~/project. Puede hacerlo haciendo clic derecho en el explorador de archivos y seleccionando "Nueva Carpeta".

mkdir my_package

A continuación, cree el archivo __init__.py requerido dentro del nuevo directorio my_package.

touch my_package/__init__.py

Ahora, mueva module_a.py al directorio my_package. Puede arrastrar y soltar el archivo en el explorador de archivos.

mv module_a.py my_package/

La estructura de su proyecto ahora debería verse así:

~/project/
├── main.py
├── hello.py
└── my_package/
    ├── __init__.py
    └── module_a.py

Con esta estructura de paquete establecida, necesitamos actualizar cómo importamos module_a en nuestro script main.py. Para importar un módulo desde un paquete, se utilizan nombres de módulo con puntos, como nombre_del_paquete.nombre_del_modulo.

Abra main.py y modifíquelo para importar la función greet desde my_package.module_a:

from my_package.module_a import greet

greet("Package")

Guarde el archivo y ejecútelo:

python3 main.py

Debería ver la siguiente salida:

Hello, Package from module_a!

Esto muestra cómo importar un objeto específico desde un módulo dentro de un paquete. Alternativamente, podría importar el módulo en sí:

## Alternative import style
import my_package.module_a

my_package.module_a.greet("Alternative")

Los paquetes son una herramienta poderosa para organizar bases de código grandes, como librerías y frameworks, en una estructura clara y mantenible.

Resumen

En este laboratorio, ha aprendido los conceptos esenciales de organización de código en Python. Comenzó comprendiendo qué es un módulo y el propósito del bloque if __name__ == "__main__": para crear código reutilizable. Luego practicó la importación de módulos usando la sintaxis import nombre_del_modulo y el acceso a sus miembros con la notación de punto.

Además, exploró la sentencia from...import para traer objetos específicos de un módulo directamente al namespace de su script. Finalmente, aprendió cómo estructurar módulos relacionados en un paquete creando un directorio con un archivo __init__.py, y cómo importar desde ese paquete. Estas habilidades son fundamentales para escribir aplicaciones Python limpias, organizadas y escalables.