Módulos y paquetes en Python: import, stdlib, pip y entornos virtuales
- Python viene con las pilas incluidas
- import: las cinco formas de importar
- Biblioteca estándar: los módulos que más usarás
- Crear tus propios módulos
- Paquetes: módulos organizados en carpetas
- pip: instalar paquetes de terceros
- Entornos virtuales con venv
- Programa completo: proyecto bien estructurado
- Errores clásicos con módulos
- Preguntas frecuentes
Python tiene fama de venir con las pilas incluidas. No es un eslogan vacío: la biblioteca estándar incluye más de 200 módulos que resuelven desde operaciones matemáticas hasta servidores HTTP, pasando por compresión de archivos, generación de contraseñas seguras y análisis de fechas. Y cuando la stdlib no es suficiente, PyPI tiene más de 500.000 paquetes a un pip install de distancia.
Saber importar bien, organizar el propio código en módulos y gestionar dependencias con entornos virtuales es lo que distingue un script de un proyecto real.
📥 import: las cinco formas de importar
# 1. Importar el módulo completo (acceso con prefijo)
import math
math.sqrt(16) # 4.0
math.pi # 3.141592...
# 2. Importar nombres específicos (sin prefijo)
from math import sqrt, pi, ceil
sqrt(25) # 5.0
# 3. Alias — nombre corto por convención
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
np.array([1, 2, 3])
# 4. Importar subpaquete
import os.path
os.path.exists("config.json")
from pathlib import Path # más común
Path("config.json").exists()
# 5. Importar todo — evitar siempre
from os import * # ⚠ contamina el namespace local
# Cuándo usar cada forma:
# import módulo → cuando usas pocas cosas del módulo
# from módulo import X → cuando usas X muchas veces
# import módulo as m → convención de terceros (numpy, pandas...)
📚 Biblioteca estándar: los módulos que más usarás
## os — sistema operativo
import os
os.getcwd() # directorio actual
os.listdir(".") # listar archivos
os.environ.get("HOME") # variables de entorno
os.path.join("data", "f.csv") # unir rutas (mejor pathlib)
## datetime — fechas y horas
from datetime import datetime, date, timedelta
hoy = date.today()
ahora = datetime.now()
manana = hoy + timedelta(days=1)
ahora.strftime("%d/%m/%Y %H:%M") # "06/03/2026 14:30"
datetime.strptime("2026-03-06", "%Y-%m-%d") # parse
## random — aleatoriedad
import random
random.randint(1, 10) # entero entre 1 y 10
random.choice(["a", "b", "c"]) # elemento aleatorio
random.shuffle(lista) # mezclar in-place
random.sample(lista, 3) # 3 elementos sin repetir
random.seed(42) # reproducibilidad
## collections — estructuras avanzadas
from collections import Counter, defaultdict, deque, namedtuple
Counter("banana") # Counter({'a':3,'n':2,'b':1})
d = defaultdict(list) # sin KeyError al añadir
d["clave"].append(1)
cola = deque([1,2,3], maxlen=3) # cola de tamaño fijo
Punto = namedtuple("Punto", ["x","y"])
p = Punto(10, 20); p.x # 10
## logging — logs profesionales
import logging
logging.basicConfig(level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s")
logging.info("Aplicación iniciada")
logging.warning("Disco casi lleno")
logging.error("Conexión fallida")
pip install metes en el carrito exactamente lo que necesitas para tu proyecto. Fuente: Pexels (licencia libre).🧩 Crear tus propios módulos
Cualquier archivo .py es un módulo importable. Dividir el código en módulos hace que sea más fácil leer, reutilizar y probar.
# ── archivo: utils.py ──────────────────────────────
"""Utilidades de formato para la aplicación."""
IVA = 0.21 # constante del módulo
def precio_con_iva(precio_base):
"""Devuelve el precio final aplicando IVA."""
return round(precio_base * (1 + IVA), 2)
def formatear_euros(cantidad):
"""Formatea una cantidad como string en euros."""
return f"{cantidad:,.2f} €".replace(",", ".")
def es_email_valido(email):
"""Comprobación básica de formato de email."""
return "@" in email and "." in email.split("@")[-1]
# ── archivo: main.py ───────────────────────────────
import utils
precio = utils.precio_con_iva(100)
print(utils.formatear_euros(precio)) # "121,00 €"
# O importando nombres directamente:
from utils import precio_con_iva, formatear_euros
print(formatear_euros(precio_con_iva(250))) # "302,50 €"
# utils.py con bloque de prueba protegido
def precio_con_iva(precio_base):
return round(precio_base * 1.21, 2)
if __name__ == "__main__":
# Este bloque SOLO se ejecuta con: python utils.py
# NO se ejecuta cuando haces: import utils
print(precio_con_iva(100)) # 121.0
print(precio_con_iva(250)) # 302.5
📦 Paquetes: módulos organizados en carpetas
# Estructura de un proyecto bien organizado:
# mi_app/
# ├── main.py
# ├── requirements.txt
# └── mi_app/
# ├── __init__.py ← hace de esta carpeta un paquete
# ├── config.py
# ├── modelos.py
# └── utils/
# ├── __init__.py
# ├── formato.py
# └── validacion.py
# __init__.py puede estar vacío o definir qué se exporta:
# mi_app/__init__.py
from .config import Config
from .modelos import Usuario, Producto
# Importar desde el paquete:
from mi_app import Config
from mi_app.utils.formato import formatear_euros
from mi_app.utils import validacion
# Importación relativa (dentro del paquete):
# en modelos.py:
from .config import Config # mismo nivel
from ..utils.formato import f # nivel superior
⚙️ pip: instalar paquetes de terceros
# En la terminal (no en el script Python):
# Instalar
pip install requests
pip install requests==2.31.0 # versión exacta
pip install "requests>=2.28,<3.0" # rango de versiones
pip install -r requirements.txt # desde lista
# Información
pip list # paquetes instalados
pip show requests # detalles de un paquete
pip search término # buscar (desactivado, usar pypi.org)
# Actualizar / desinstalar
pip install --upgrade requests
pip uninstall requests
# Guardar dependencias del proyecto
pip freeze > requirements.txt # snapshot exacto
🧪 Entornos virtuales con venv
Sin entorno virtual, todos tus proyectos comparten los mismos paquetes instalados globalmente. Si dos proyectos necesitan versiones distintas del mismo paquete, hay conflicto. venv crea un espacio aislado por proyecto.
# En la terminal:
# 1. Crear el entorno virtual
python -m venv venv # crea carpeta "venv/"
python -m venv .venv # convención: carpeta oculta
# 2. Activar
source venv/bin/activate # Unix / macOS
venv\Scripts\activate # Windows (cmd)
venv\Scripts\Activate.ps1 # Windows (PowerShell)
# El prompt cambia a: (venv) usuario@máquina:~/proyecto$
# 3. Instalar paquetes (solo en este entorno)
pip install requests flask pandas
# 4. Guardar dependencias
pip freeze > requirements.txt
# 5. Desactivar cuando termines
deactivate
# Recrear el entorno en otra máquina:
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
🛠️ Programa completo: proyecto bien estructurado
# Estructura del proyecto:
# conversor/
# ├── main.py
# ├── requirements.txt (vacío — solo stdlib)
# └── conversor/
# ├── __init__.py
# ├── divisas.py
# ├── temperaturas.py
# └── utils.py
# ── conversor/utils.py ──────────────────────────
"""Utilidades compartidas."""
import logging
from datetime import datetime
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%H:%M:%S"
)
logger = logging.getLogger(__name__)
def redondear(valor, decimales=2):
return round(valor, decimales)
def timestamp():
return datetime.now().strftime("%H:%M:%S")
# ── conversor/temperaturas.py ───────────────────
"""Conversiones de temperatura."""
from .utils import redondear, logger
def celsius_a_fahrenheit(c):
resultado = redondear(c * 9/5 + 32)
logger.info(f"{c}°C → {resultado}°F")
return resultado
def fahrenheit_a_celsius(f):
resultado = redondear((f - 32) * 5/9)
logger.info(f"{f}°F → {resultado}°C")
return resultado
def celsius_a_kelvin(c):
return redondear(c + 273.15)
# ── conversor/divisas.py ────────────────────────
"""Conversiones de divisas (tasas de ejemplo)."""
from .utils import redondear, logger
TASAS = {
("EUR", "USD"): 1.08,
("USD", "EUR"): 0.93,
("EUR", "GBP"): 0.85,
("GBP", "EUR"): 1.18,
}
def convertir(cantidad, origen, destino):
clave = (origen.upper(), destino.upper())
if clave not in TASAS:
raise ValueError(f"Par no disponible: {origen}/{destino}")
resultado = redondear(cantidad * TASAS[clave])
logger.info(f"{cantidad} {origen} → {resultado} {destino}")
return resultado
# ── main.py ─────────────────────────────────────
from conversor.temperaturas import celsius_a_fahrenheit, fahrenheit_a_celsius
from conversor.divisas import convertir
def menu():
while True:
print("\n=== CONVERSOR ===")
print("1. Temperatura 2. Divisas 3. Salir")
op = input("Opción: ").strip()
if op == "1":
valor = float(input("Celsius: "))
print(f" → {celsius_a_fahrenheit(valor)} °F")
elif op == "2":
cant = float(input("Cantidad: "))
orig = input("De (ej. EUR): ").strip()
dest = input("A (ej. USD): ").strip()
try:
print(f" → {convertir(cant, orig, dest)} {dest}")
except ValueError as e:
print(f" Error: {e}")
elif op == "3":
break
if __name__ == "__main__":
menu()
🐛 Errores clásicos con módulos
1. Archivo con el mismo nombre que un módulo de stdlib
# ❌ Si tienes un archivo llamado random.py en tu proyecto:
import random # importa TU random.py, no la stdlib
random.randint(1,10) # AttributeError: sin randint
# ✅ Renombra tu archivo: mi_random.py, generador.py...
# Para verificar qué se está importando:
import random; print(random.__file__)
2. Instalar paquete globalmente cuando deberías usar venv
# ❌ Sin activar el entorno virtual:
pip install flask # se instala globalmente
# ✅ Siempre con el entorno activado:
source venv/bin/activate
pip install flask # solo en este proyecto
3. ImportError por olvidar __init__.py (Python < 3.3)
# Si tu paquete no tiene __init__.py en Python 2 o entornos legacy:
# ImportError: No module named 'mi_paquete'
# ✅ Crear __init__.py (puede estar vacío):
# mi_paquete/__init__.py ← aunque esté vacío, es necesario
4. Importación circular
# ❌ a.py importa b.py, b.py importa a.py → ImportError circular
# a.py: from b import funcion_b
# b.py: from a import funcion_a ← círculo
# ✅ Soluciones:
# - Mover el código compartido a un tercer módulo (utils.py)
# - Importar dentro de la función, no a nivel de módulo
# - Reorganizar las dependencias
✅ Resumen y próximos pasos
Los módulos son la unidad de reutilización de Python. La stdlib resuelve el 80% de los problemas sin instalar nada. Para el resto, pip descarga paquetes de PyPI. Los entornos virtuales aíslan las dependencias por proyecto — siempre uno por proyecto. Y dividir el código propio en módulos y paquetes hace que escale sin convertirse en un monolito inmanejable.
La siguiente lección: Programación orientada a objetos — clases, objetos, atributos, métodos y herencia. El salto a Módulo 4.
❓ Preguntas frecuentes
❓ Preguntas frecuentes sobre Módulos y paquetes en Python: import, stdlib, pip y entornos virtuales
Las dudas más comunes respondidas de forma clara y directa.
💬 Foro de discusión
¿Tienes dudas sobre Módulos y paquetes en Python: import, stdlib, pip y entornos virtuales? Comparte tu pregunta con la comunidad.
Todavía no hay mensajes. ¡Sé el primero en participar!