En esta página
Módulos y paquetes
¿Qué es un módulo?
Un módulo en Python es simplemente un archivo .py. Todo lo que defines en ese archivo (funciones, clases, constantes) es accesible desde otros archivos Python al importar el módulo. Los módulos son la forma más básica de organización de código en Python.
La biblioteca estándar de Python incluye cientos de módulos integrados. Cuando instalas Python, obtienes os, sys, math, json, datetime, pathlib y muchos más, listos para usar sin instalación adicional.
Importaciones básicas
# Importar el módulo completo
import math
import os
import sys
print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
print(math.factorial(5)) # 120
# Acceso al sistema
print(os.getcwd()) # Directorio de trabajo actual
print(sys.version) # Versión de Python
print(sys.platform) # 'linux', 'win32', 'darwin'from...import — Importar nombres específicos
# Importar funciones/clases específicas
from math import sqrt, pi, factorial
from os.path import join, exists, dirname
from datetime import datetime, timedelta
# Ahora usas los nombres directamente (sin prefijo)
print(sqrt(25)) # 5.0
print(pi) # 3.141592653589793
# Con alias — para nombres muy largos o conflictos
from collections import OrderedDict as OD
from datetime import datetime as dt
ahora = dt.now()
print(ahora.strftime("%Y-%m-%d %H:%M:%S"))
# Importar todo (¡úsalo con moderación!)
from math import *
# Ahora tienes sin, cos, tan, etc. directamente
# ¡Pero puede contaminar el espacio de nombres!Alias con as
# Alias de módulo completo (convenciones comunes en la industria)
import numpy as np # Convención estándar de NumPy
import pandas as pd # Convención estándar de Pandas
import matplotlib.pyplot as plt # Convención estándar
# Alias de nombres específicos para evitar conflictos
from email.message import Message as EmailMessage
from http.server import BaseHTTPRequestHandler as HTTPHandlerEl guardián __name__ == "__main__"
Cuando Python ejecuta un archivo directamente, establece __name__ = "__main__". Cuando el archivo se importa desde otro módulo, __name__ toma el nombre del módulo:
# archivo: utilidades.py
def calcular_iva(precio: float, tasa: float = 0.21) -> float:
"""Calcula el IVA de un precio."""
return precio * tasa
def precio_con_iva(precio: float) -> float:
"""Devuelve el precio total con IVA incluido."""
return precio + calcular_iva(precio)
def main() -> None:
"""Función principal para pruebas del módulo."""
precios_prueba = [10.0, 50.0, 100.0, 250.0]
for precio in precios_prueba:
total = precio_con_iva(precio)
print(f"Precio: ${precio:.2f} → Total con IVA: ${total:.2f}")
if __name__ == "__main__":
# Solo se ejecuta si corres: python utilidades.py
# NO se ejecuta si otro archivo hace: import utilidades
main()Creando tu propio paquete
Un paquete es un directorio que contiene módulos y un archivo especial __init__.py. La estructura típica:
mi_proyecto/
├── __init__.py # Convierte el directorio en paquete
├── models.py
├── utils.py
├── validators.py
└── api/
├── __init__.py
├── routes.py
└── handlers.pyEl archivo __init__.py
# archivo: mi_paquete/__init__.py
"""
Mi Paquete — Biblioteca de utilidades para proyectos Python.
"""
# Puedes importar y re-exportar para simplificar el API del paquete
from .models import Usuario, Producto
from .utils import formatear_precio, calcular_descuento
from .validators import validar_email, validar_telefono
# Definir qué se exporta con import *
__all__ = ["Usuario", "Producto", "formatear_precio", "validar_email"]
# Versión del paquete
__version__ = "1.0.0"
__author__ = "David Morales Vega"Importaciones relativas
Dentro de un paquete, usas importaciones relativas con puntos:
# archivo: mi_paquete/models.py
from .utils import formatear_precio # Importar desde el mismo paquete
from .api.routes import listar_recursos # Importar desde un subpaquete
from ..config import BASE_URL # Importar del paquete padrepip — El gestor de paquetes de Python
pip (Package Installer for Python) te permite instalar, actualizar y desinstalar paquetes del Python Package Index (PyPI), que tiene más de 500.000 paquetes.
# Instalar un paquete
pip install requests
# Instalar una versión específica
pip install requests==2.31.0
# Instalar con restricciones de versión
pip install "requests>=2.28,<3.0"
# Actualizar un paquete
pip install --upgrade requests
# Desinstalar
pip uninstall requests
# Ver qué paquetes están instalados
pip list
pip freeze # Formato requirements.txt (para reproducibilidad)
# Ver información de un paquete
pip show requests
# Buscar paquetes (se eliminó en versiones recientes, usa pypi.org)
pip search requests # Puede no estar disponible
# Instalar desde requirements.txt
pip install -r requirements.txtrequirements.txt — Reproducibilidad de dependencias
El archivo requirements.txt lista todas las dependencias del proyecto con sus versiones exactas:
# Generar desde el entorno actual
pip freeze > requirements.txtContenido típico de requirements.txt:
requests==2.31.0
httpx==0.27.0
pydantic==2.5.3
fastapi==0.108.0
uvicorn==0.25.0
python-dotenv==1.0.0Para proyectos más serios, considera pyproject.toml con herramientas como poetry o hatch.
Entornos virtuales con venv
Un entorno virtual es un directorio aislado que contiene su propia instalación de Python y paquetes. Esto evita conflictos entre proyectos:
# Crear un entorno virtual en el directorio .venv
python3.14 -m venv .venv
# Activar el entorno virtual
# En macOS/Linux:
source .venv/bin/activate
# En Windows (PowerShell):
.venv\Scripts\Activate.ps1
# En Windows (CMD):
.venv\Scripts\activate.bat
# Verificar que está activo — el prompt cambia a (.venv)
which python # macOS/Linux → muestra la ruta del venv
where python # Windows
# Instalar dependencias en el entorno virtual
pip install fastapi uvicorn
# Desactivar el entorno virtual
deactivate
# Eliminar el entorno virtual (simplemente borra el directorio)
rm -rf .venvFlujo de trabajo recomendado
# 1. Crear el proyecto
mkdir mi_proyecto
cd mi_proyecto
# 2. Crear entorno virtual
python3.14 -m venv .venv
# 3. Activar
source .venv/bin/activate # macOS/Linux
# 4. Instalar dependencias
pip install fastapi uvicorn pydantic
# 5. Guardar dependencias
pip freeze > requirements.txt
# 6. Agregar .venv al .gitignore
echo ".venv/" >> .gitignoreMódulos de la biblioteca estándar más útiles
os y pathlib
import os
from pathlib import Path
# pathlib (modo moderno, preferido en Python 3.4+)
ruta = Path("datos") / "usuarios" / "ana.json"
print(ruta) # datos/usuarios/ana.json
print(ruta.parent) # datos/usuarios
print(ruta.name) # ana.json
print(ruta.stem) # ana
print(ruta.suffix) # .json
# Operaciones de archivos
ruta.parent.mkdir(parents=True, exist_ok=True) # Crear directorios
ruta.write_text('{"nombre": "Ana"}', encoding="utf-8")
contenido = ruta.read_text(encoding="utf-8")
ruta.unlink() # Eliminar
# Listar archivos
directorio = Path(".")
for archivo in directorio.glob("*.py"):
print(archivo.name)
for archivo in directorio.rglob("*.json"): # Recursivo
print(archivo)datetime
from datetime import datetime, timedelta, timezone
# Fecha y hora actual
ahora = datetime.now()
ahora_utc = datetime.now(timezone.utc)
# Crear fechas específicas
nacimiento = datetime(1990, 5, 15, 10, 30, 0)
# Formatear
print(ahora.strftime("%d/%m/%Y %H:%M")) # 02/04/2026 15:30
print(ahora.isoformat()) # 2026-04-02T15:30:00
# Aritmética de fechas
manana = ahora + timedelta(days=1)
hace_una_semana = ahora - timedelta(weeks=1)
diferencia = ahora - nacimiento
print(f"Han pasado {diferencia.days} días")
# Parsear una fecha desde string
fecha_str = "2026-01-15"
fecha = datetime.strptime(fecha_str, "%Y-%m-%d")collections y itertools
from collections import Counter, defaultdict, deque, namedtuple
from itertools import chain, product, combinations, permutations
# namedtuple — tupla con campos nombrados (ligera y legible)
Punto = namedtuple("Punto", ["x", "y", "z"])
p = Punto(1, 2, 3)
print(p.x, p.y, p.z) # 1 2 3
print(p) # Punto(x=1, y=2, z=3)
# deque — cola de doble extremo, O(1) en ambos lados
cola: deque[str] = deque(maxlen=5) # Descarta los más antiguos
cola.append("a")
cola.appendleft("z")
print(cola.popleft()) # 'z'
# Combinaciones y permutaciones
letras = ["A", "B", "C"]
for combo in combinations(letras, 2):
print(combo) # ('A', 'B'), ('A', 'C'), ('B', 'C')
for perm in permutations(letras, 2):
print(perm) # ('A', 'B'), ('A', 'C'), ('B', 'A'), ...Resumen
Los módulos y paquetes son el sistema de organización del código Python. El bloque if __name__ == "__main__" separa el código ejecutable del código importable. Los entornos virtuales con venv son imprescindibles para gestionar dependencias por proyecto. En la próxima lección exploraremos la programación orientada a objetos con clases y todos sus mecanismos.
Inicia sesión para guardar tu progreso