Módulos y paquetes de Python: import, pip, venv y bibliotecas explicados con sencillez
Un módulo en Python es un archivo .py, un paquete es una carpeta de módulos y una biblioteca es un conjunto de paquetes que se incorpora con import. Las bibliotecas de terceros se instalan con pip (o uv) dentro de un entorno virtual venv, una carpeta aislada con su propio intérprete y sus paquetes, para que las versiones de distintos proyectos no entren en conflicto.
Un módulo en Python es un archivo normal con código, y import es la forma de tomar de él funciones y clases. Con los módulos se forman los paquetes, con los paquetes se forman las bibliotecas, y para que las bibliotecas de terceros de distintos proyectos no se estorben entre sí se instalan en un entorno virtual venv. Vamos a repasar toda la cadena: qué ocurre al importar, cómo está organizado un paquete, cómo funcionan pip y venv en Python y qué son los imports perezosos que llegaron en Python 3.15.
Módulo, paquete, biblioteca: en qué se diferencian
| Concepto | Qué es | Ejemplo |
|---|---|---|
| Módulo | Un único archivo .py; el nombre del módulo es el nombre del archivo sin extensión | categorias.py → import categorias |
| Paquete | Una carpeta con módulos y un archivo __init__.py | gastos/informe.py → from gastos.informe import construir |
| Biblioteca | Un conjunto listo de módulos y paquetes para una tarea | requests, pandas, la estándar pathlib |
| Distribución (paquete de PyPI) | Un archivo que instala pip | pip install requests |
En la conversación, «biblioteca», «paquete» y «módulo» se mezclan a menudo; no pasa nada. Lo importante es que, técnicamente, import carga siempre un módulo o un paquete, y pip instala una distribución de PyPI, dentro de la cual hay paquetes.
Cómo funciona import en Python
Hay varias formas de importar, y todas aparecen en código real:
import math # el módulo completo, uso math.sqrt
from math import sqrt, pi # nombres concretos
import datetime as dt # alias
from collections import Counter as C
print(math.sqrt(16), sqrt(9), pi)
print(dt.date.today())
Los alias son habituales en las bibliotecas grandes: import numpy as np, import pandas as pd. La construcción from modulo import * conviene evitarla: llena el espacio de nombres y oculta de dónde viene cada nombre.
Qué hace import realmente
- Busca el módulo en la caché
sys.modules. Si ya está cargado, simplemente lo devuelve. - Si no está, busca el archivo en las carpetas de
sys.path: la carpeta del script que se ejecuta, la biblioteca estándar, el site-packages del entorno. - Ejecuta el archivo encontrado completo, de arriba abajo.
- Guarda el objeto del módulo en la caché y lo asocia al nombre.
De aquí se derivan dos conclusiones prácticas. Volver a importar el mismo módulo es casi gratis: el código no se vuelve a ejecutar. Y todo el código de nivel superior del módulo, incluidos los print y los cálculos pesados, se ejecuta al importarlo.
import sys
for p in sys.path:
print(p)
print("math" in sys.modules)
if __name__ == "__main__"
Como importar ejecuta el archivo, hace falta una forma de distinguir «me han ejecutado como script» de «me han importado». Para eso existe la variable __name__: al ejecutar el archivo vale "__main__", y al importarlo, el nombre del módulo.
# categorias.py
def adivinar(titulo: str) -> str:
return "comida" if "café" in titulo.lower() else "otros"
if __name__ == "__main__":
print(adivinar("Café de casa")) # se ejecuta solo con python categorias.py
Para un paquete existe una alternativa: un archivo __main__.py dentro y el arranque con python -m gastos.
Módulos estándar de Python
Python viene «con pilas incluidas»: cientos de módulos integrados están disponibles sin instalar nada. Los más usados:
| Módulo | Para qué sirve |
|---|---|
os, sys, pathlib, shutil | Sistema, rutas y archivos |
json, csv, pickle | Formatos de datos |
datetime, time, calendar | Fecha y hora |
math, random, statistics, fractions | Números |
re, string | Trabajo con texto |
collections, itertools, functools | Estructuras de datos e iteradores |
logging, argparse, subprocess | Registros, argumentos de línea de comandos, ejecución de programas |
asyncio, threading | Asincronía e hilos |
La lista completa de módulos de la biblioteca estándar está en sys.stdlib_module_names (Python 3.10 o superior). Para ver qué contiene un módulo se usan dir(math) y help(math).
Paquete propio: estructura del proyecto
Cuando hay muchos módulos, se agrupan en un paquete. Una disposición habitual es el src-layout:
gastos-proyecto/
├── pyproject.toml
└── src/
└── gastos/
├── __init__.py
├── cli.py
├── analisis.py
├── categorias.py
└── informe.py
Dentro del paquete, los módulos se importan entre sí por el nombre del paquete (from gastos.categorias import adivinar) o de forma relativa (from .categorias import adivinar). La importación relativa solo funciona dentro del paquete, no en un archivo ejecutado directamente como script.
pip en Python: instalar bibliotecas
Las bibliotecas de terceros están en el catálogo PyPI, y las instala la utilidad pip, que viene con Python. Lo más seguro es invocarla a través del intérprete: así la biblioteca acaba exactamente en el Python con el que ejecuta su código.
python -m pip install requests # instalar
python -m pip install "pandas>=2.3" # con restricción de versión
python -m pip install --upgrade requests
python -m pip uninstall requests # desinstalar
python -m pip list # lista de paquetes instalados
python -m pip show requests # versión y dependencias
python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt
En Windows, en lugar de python se suele usar el lanzador py. Si pip no se encuentra, lo instala el módulo integrado: python -m ensurepip --upgrade.
Bibliotecas populares de Python
En PyPI hay cientos de miles de paquetes, pero en la mayoría de los proyectos aparece siempre la misma lista corta. Conviene empezar por ella, en lugar de buscar exotismos.
| Tarea | Bibliotecas |
|---|---|
| Peticiones HTTP y APIs | requests, httpx |
| Análisis de datos y tablas | pandas, numpy |
| Gráficos | matplotlib |
| Servicios web | fastapi, django, flask |
| Pruebas | pytest |
| Imágenes | pillow (se importa como PIL) |
Ojo: el nombre para instalar y el nombre para importar no siempre coinciden. Se instala pip install pillow, pero se escribe from PIL import Image; se instala opencv-python, pero se importa cv2. Si import falla justo después de instalar, compruebe en la documentación del paquete con qué nombre se importa.
Instalar bibliotecas en Linux
En las versiones recientes de Debian y Ubuntu, el comando pip install en el Python del sistema termina con el error externally-managed-environment (PEP 668). Es una protección: el Python del sistema pertenece al gestor de paquetes del sistema operativo, y pip no debe romperlo. La solución correcta no es --break-system-packages, sino un entorno virtual.
venv en Python: entorno virtual
Un entorno virtual es una carpeta independiente con su propia copia del intérprete (un enlace a él) y su propio site-packages. Las bibliotecas instaladas en él solo son visibles para ese proyecto. Así, un proyecto puede usar Django 4 y otro, Django 5, sin conflictos.
El módulo venv viene integrado en Python y no hace falta instalarlo aparte (en Debian/Ubuntu a veces se necesita el paquete del sistema python3-venv).
# crear el entorno en la carpeta .venv
python -m venv .venv
# activar: Linux y macOS
source .venv/bin/activate
# activar: Windows PowerShell
.venv\Scripts\Activate.ps1
# ahora pip instala los paquetes dentro de .venv
python -m pip install requests
python -c "import sys; print(sys.prefix)"
# salir del entorno
deactivate
Tras activar el entorno, al principio de la línea del terminal aparece (.venv). La carpeta del entorno no se sube a git (añada .venv/ a .gitignore) ni se traslada entre equipos: en su lugar se guarda la lista de dependencias y el entorno se vuelve a crear. Si PowerShell impide ejecutar el script de activación, permítalo para el usuario con Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.
uv y pyproject.toml
Los proyectos modernos describen sus dependencias en pyproject.toml. El gestor uv, que usamos en el curso, combina la creación del entorno y la instalación: uv add pandas descarga el paquete, lo añade a pyproject.toml y fija las versiones exactas en uv.lock. Un compañero clona el proyecto, ejecuta uv sync y obtiene exactamente el mismo entorno.
[project]
name = "gastos"
version = "0.1.0"
requires-python = ">=3.15"
dependencies = [
"pandas>=2.3",
]
[project.scripts]
gastos = "gastos.cli:main"
Imports perezosos en Python 3.15 (PEP 810)
La novedad principal de la versión 3.15 en este tema es la palabra clave lazy. Las bibliotecas pesadas tardan en cargarse: en la medición del curso, con la imagen python:3.15-slim, un import pandas normal tardó unos 415 ms, y lazy import pandas, unos 13 ms. Para una utilidad de línea de comandos que se lanza para ver --help, la diferencia es enorme.
lazy import pandas as pd
lazy from gastos.informe import construir_informe
def main() -> None:
...
df = pd.read_csv(ruta) # aquí se carga pandas de verdad
En lugar del módulo, el nombre recibe un objeto proxy (types.LazyImportType), y la importación real se hace en el primer uso del nombre. Si ese uso nunca llega, no se pierde tiempo en absoluto.
Limitaciones de lazy import
- Solo se permite en el nivel superior del módulo: dentro de una función, una clase o un
try/exceptproduceSyntaxError. lazy from x import *está prohibido.ModuleNotFoundErroraparece no al arrancar, sino en el primer uso.- Los efectos secundarios del módulo (registro de complementos, etc.) se desplazan en el tiempo.
Para hacer perezosos todos los imports a la vez se usa el indicador -X lazy_imports=all o la variable PYTHON_LAZY_IMPORTS=all, y las excepciones se definen con sys.set_lazy_imports_filter(). Para un código que debe funcionar también en versiones antiguas existe la variable del módulo __lazy_modules__ = ["pandas"]: Python 3.15 hará perezosos los imports indicados, y las versiones antiguas simplemente ejecutarán un import normal. Para ver dónde se gasta el tiempo al arrancar, sirve python -X importtime -c "import pandas". Se benefician sobre todo los programas que se lanzan a menudo y durante poco tiempo; un servidor de larga duración apenas gana nada con la carga perezosa.
Errores típicos
ModuleNotFoundError: No module named 'requests': la biblioteca se instaló en otro Python o el entorno no está activado. Compruebe conpython -m pip show requestsusando el mismo intérprete.- Un archivo propio se llama
json.py,random.pyocsv.py: la carpeta del script ocupa el primer lugar ensys.pathy tapa el módulo estándar. Python 3.13 y superiores sugieren «consider renaming» en el error. Cambie el nombre del archivo y borre__pycache__. - Importación circular:
a.pyimportab.py, y este, aa.py. Saque lo común a un tercer módulo o importe dentro de una función. - Ejecutar pip dentro del intérprete (
>>> pip install) produceSyntaxError. Los comandos de pip se ejecutan en la terminal.
Resumen
El módulo es un archivo, el paquete es una carpeta de módulos y la biblioteca es su conjunto listo; import busca el módulo en la caché y en sys.path, y lo ejecuta una sola vez. Instale las bibliotecas de terceros con pip o uv solo dentro de un entorno virtual venv: así los proyectos no se estorban y el entorno se puede reproducir fácilmente. En el curso de Python este tema se practica convirtiendo el registro de gastos en un paquete con dependencias y un arranque rápido gracias a los imports perezosos.
Preguntas frecuentes
¿Hay que crear un venv para cada proyecto?
Sí, es una buena práctica: cada proyecto tiene sus propias versiones de las bibliotecas, y un entorno aparte evita conflictos y no ensucia el Python del sistema.
¿En qué se diferencia pip de uv?
pip solo instala paquetes; uv además crea el entorno, anota las dependencias en pyproject.toml y fija las versiones exactas en un archivo de bloqueo. Además, es bastante más rápido.
¿Cómo ver la lista de bibliotecas instaladas en Python?
Ejecute python -m pip list en el entorno correspondiente; pip freeze muestra la misma lista en el formato de requirements.txt.
¿Dónde se guardan los módulos instalados?
En la carpeta site-packages del entorno actual. La ruta de un módulo concreto la indica su atributo __file__: por ejemplo, import requests; print(requests.__file__).
¿Se puede copiar la carpeta venv a otro ordenador?
No: el entorno está ligado a las rutas y al intérprete de la máquina. Lo que se traslada es la lista de dependencias, y el entorno se crea de nuevo.
Este tema se explica a fondo y con práctica en el curso «Python 3.15: от новичка до профи».
Ir al curso