Lección 10 de 12 · Nivel 3: Avanzado
Módulos, paquetes, pip y entornos virtuales en Python
En esta lección
- Dividir un programa en varios archivos (módulos) y paquetes.
- Instalar librerías con
pipy aislarlas en un entorno virtual. - Compartir tu proyecto para que funcione en otra computadora.
- Escribir tus primeras pruebas automáticas con
pytest.
Un script de 50 líneas cabe en un archivo. Un proyecto real, no. En esta lección aprenderás a organizar el código como lo hacen los equipos profesionales y a manejar las librerías externas, que son la verdadera fuerza de Python: hay cientos de miles disponibles para casi cualquier tarea.
Módulos: tu código en varios archivos
Un módulo es simplemente un archivo .py. Lo que defines en él se puede importar desde otro archivo de la misma carpeta.
# archivo: finanzas.py
IMPUESTO = 0.18
def precio_con_impuesto(precio):
return round(precio * (1 + IMPUESTO), 2)
def cuota_prestamo(monto, tasa_anual, meses):
r = (1 + tasa_anual) ** (1 / 12) - 1
return round(monto * r / (1 - (1 + r) ** -meses), 2)
# archivo: main.py
import finanzas
from finanzas import cuota_prestamo
print(finanzas.precio_con_impuesto(100)) # 118.0
print(cuota_prestamo(10000, 0.24, 24)) # 517.33
Las tres formas de importar:
import finanzas: usasfinanzas.funcion(). Es la más clara: siempre sabes de dónde viene cada cosa.from finanzas import cuota_prestamo: importas solo lo que necesitas.import pandas as pd: con un alias corto, muy común en librerías grandes.
Evita from modulo import *: trae todo sin que sepas qué, y puede pisar tus propios nombres.
El significado de if __name__ == "__main__"
Cuando importas un módulo, Python ejecuta todo su código. Si finanzas.py tuviera un print de prueba suelto, aparecería al importarlo. Por eso el código "de ejecución" se protege así (lo viste en la lección 7):
if __name__ == "__main__":
print(cuota_prestamo(5000, 0.2, 12)) # solo se ejecuta al lanzar este archivo directamente
Paquetes: carpetas de módulos
Cuando tienes muchos módulos, agrúpalos en carpetas. Una carpeta con un archivo __init__.py (puede estar vacío) es un paquete:
gestor_gastos/
├── main.py
├── requirements.txt
├── gastos/
│ ├── __init__.py
│ ├── modelos.py ← clases (lección 9)
│ ├── almacen.py ← leer y guardar el CSV
│ └── reportes.py ← resúmenes
└── tests/
└── test_reportes.py
# en main.py
from gastos.modelos import Gasto
from gastos import reportes
1. Tienes un archivo utilidades.py con una función limpiar_texto. ¿Cómo la usas desde main.py en la misma carpeta?
Sintaxis de Python: from módulo import nombre, sin la extensión .py.
pip: instalar librerías
pip es el instalador de paquetes de Python. Descarga librerías del repositorio oficial PyPI:
pip install requests # instalar
pip install pandas==3.0.0 # una versión concreta (ejemplo)
pip install --upgrade pandas # actualizar
pip list # ver lo instalado
pip uninstall requests # desinstalar
Si pip no se reconoce como comando, usa python -m pip install … (o python3 -m pip en macOS y Linux). Esta forma garantiza que instalas para el mismo Python que ejecutas.
Cualquiera puede publicar en PyPI, y existen paquetes maliciosos con nombres parecidos a los populares (por ejemplo, reqeusts en lugar de requests). Revisa bien el nombre y comprueba que el paquete sea conocido y mantenido.
Entornos virtuales: un Python por proyecto
Si instalas todo "globalmente", tarde o temprano dos proyectos necesitarán versiones distintas de la misma librería y uno de ellos se romperá. Un entorno virtual es una carpeta con su propio Python y sus propias librerías, aislada del resto.
# 1. Crear el entorno (una vez por proyecto, dentro de su carpeta)
python -m venv .venv
# 2. Activarlo (cada vez que abras una terminal nueva)
.venv\Scripts\activate # Windows
source .venv/bin/activate # macOS y Linux
# 3. Instalar lo que necesites: queda dentro de .venv
pip install pandas requests
# 4. Salir del entorno
deactivate
Cuando el entorno está activo, la terminal muestra (.venv) al principio de la línea. VS Code detecta la carpeta .venv y te ofrece usarla automáticamente.
2. ¿Para qué sirve un entorno virtual?
Aísla las dependencias: lo que instalas en el entorno de un proyecto no afecta a los demás.
requirements.txt: que tu proyecto funcione en otra computadora
pip freeze > requirements.txt # guarda la lista exacta de librerías instaladas
pip install -r requirements.txt # en otra computadora, instala todo de una vez
Comparte el código y el requirements.txt, nunca la carpeta .venv (es pesada y depende del sistema operativo). Si usas Git, añade .venv/ a tu archivo .gitignore. Si todavía no usas Git, tenemos una guía para instalar Git Bash.
Existen gestores más rápidos y completos, como uv o poetry, que crean el entorno, instalan y fijan versiones con un solo comando. Cuando domines venv y pip, vale la pena probarlos.
Pruebas automáticas con pytest
Una prueba es código que comprueba que otro código funciona. Con pruebas puedes cambiar tu programa sin miedo: si rompes algo, lo sabrás en segundos.
# archivo: test_finanzas.py
import pytest
from finanzas import precio_con_impuesto, cuota_prestamo
def test_precio_con_impuesto():
assert precio_con_impuesto(100) == 118.0
def test_cuota_prestamo():
assert cuota_prestamo(10000, 0.24, 24) == 517.33
def test_cuota_sin_meses_falla():
with pytest.raises(ZeroDivisionError):
cuota_prestamo(10000, 0.24, 0)
pip install pytest
pytest # busca los archivos test_*.py y ejecuta las funciones test_*
assert verifica que algo sea verdadero; si no lo es, la prueba falla y pytest te muestra qué esperaba y qué obtuvo. Cuando tu código depende de cosas externas (una API, la fecha de hoy), se usan "dobles" de prueba; tenemos un artículo sobre qué son los mocks.
3. ¿Qué archivo compartes para que otra persona instale las mismas librerías que tu proyecto?
Con pip install -r requirements.txt la otra persona recrea las dependencias en su propio entorno.
Estilo profesional
- PEP 8 es la guía de estilo oficial: 4 espacios de indentación,
snake_casepara funciones y variables,CamelCasepara clases, líneas no demasiado largas. - Herramientas como
ruffoblackrevisan y formatean tu código automáticamente. - Usa type hints (lección 7) y docstrings en las funciones públicas.
Reto: reorganiza tu gestor de gastos
- Crea una carpeta de proyecto con un entorno virtual.
- Divide el gestor de gastos de la lección 8 en el paquete
gastos/con los módulosmodelos.py(unadataclass Gasto),almacen.py(leer y guardar el CSV) yreportes.py(el resumen por categoría). - Deja en
main.pysolo el menú. - Escribe al menos dos pruebas para
reportes.pyy ejecútalas con pytest. - Genera el
requirements.txt.
Ejemplo de prueba para el resumen
# tests/test_reportes.py
from gastos.reportes import total_por_categoria
def test_total_por_categoria():
gastos = [{"categoria": "comida", "monto": 10.0},
{"categoria": "comida", "monto": 5.0},
{"categoria": "ocio", "monto": 20.0}]
assert total_por_categoria(gastos) == {"comida": 15.0, "ocio": 20.0}
Resumen
- Un módulo es un archivo
.py; un paquete, una carpeta con__init__.py. - Instala librerías con
pipdentro de un entorno virtual por proyecto. - Comparte
requirements.txt, no la carpeta.venv. - Las pruebas con pytest te permiten cambiar el código con confianza.
En la próxima lección usarás tu primera gran librería externa: pandas, la herramienta estándar para analizar datos en Python.
Crea tu cuenta, marca tus avances y descarga el certificado al terminar el curso.