Python 3.12+ Mastery 2026
Programación Moderna · Principios SOLID · Concurrencia Asyncio · Proyectos Reales · 14 Módulos
Capítulo 1 · Introducción a Python 3.12+ y Entorno de Desarrollo
Nivel 1 · PrincipiantePython es el lenguaje número #1 en la industria global del software en 2026, dominando desarrollo backend, ciencia de datos, inteligencia artificial, automatización, backend de microservicios y ciberseguridad. Su sintaxis clara y expresiva combinada con un ecosistema gigantesco lo convierten en una herramienta fundamental.
1.1 El Zen de Python
Ingresa import this en la consola interactiva de Python para leer las directrices de diseño de Tim Peters:
python3 >>> import this # Beautiful is better than ugly. # Explicit is better than implicit. # Simple is better than complex. # Readability counts. # Special cases aren't special enough to break the rules.
1.2 Configuración del Entorno de Desarrollo
En el desarrollo moderno se utilizan herramientas ultra rápidas como uv (de Astral) o poetry para gestionar versiones y entornos virtuales aislados.
python --version o python3 --version..\venv\Scripts\Activate.ps1. En Linux/macOS: source venv/bin/activate.# Crear directorio e iniciar venv mkdir mi_proyecto_python && cd mi_proyecto_python python -m venv venv # Activar entorno (Linux/macOS) source venv/bin/activate # O usar uv (Administrador de paquetes ultra rápido escrito en Rust) uv venv uv pip install requests pydantic pytest
venv incluido en la librería estándar se invoca mediante python -m venv nombre_entorno.Capítulo 2 · Sintaxis Básica, Variables y Tipos Primitivos
Nivel 1 · PrincipianteEn Python todo es un objeto. Las variables actúan como etiquetas de referencia que apuntan a objetos en memoria.
2.1 Tipos de Datos Primitivos
| Tipo | Ejemplo | Descripción | Mutabilidad |
|---|---|---|---|
int | 42, -1000 | Enteros de precisión arbitraria | Inmutable |
float | 3.14159, 2.5e-3 | Números de punto flotante de 64-bit | Inmutable |
str | "Hola Python" | Cadenas de caracteres Unicode | Inmutable |
bool | True, False | Booleanos (subclase de int) | Inmutable |
bytes | b"ASCII" | Secuencia inmutable de bytes | Inmutable |
NoneType | None | Representa la ausencia explícita de valor | Inmutable |
2.2 Manipulación de Strings e Interpolación
Python soporta f-strings (format strings) con expresiones avanzadas evaluadas en tiempo de ejecución:
# Variables nombre = "AutoNovations" módulos = 14 tasa_éxito = 0.985 # f-string moderno con especificaciones de formato mensaje = f"Curso {nombre.upper()} | Módulos: {módulos} | Éxito: {tasa_éxito:.1%}" print(mensaje) # Output: Curso AUTONOVATIONS | Módulos: 14 | Éxito: 98.5% # Operador de autodocumentación (=) disponible desde Python 3.8+ x = 10 y = 25 print(f"{x=}, {y=}, {x+y=}") # Output: x=10, y=25, x+y=35
2.3 Conversión de Tipos (Casting) y Operadores
# Casting explícito edad_str = "28" edad_num = int(edad_str) # Divisibilidad entera (//) y exponenciación (**) cuadrado = 5 ** 2 # 25 div_entera = 17 // 5 # 3 modulo = 17 % 5 # 2 # Operadores Lógicos (and, or, not) y de Pertenencia (in, not in) es_valido = 18 <= edad_num and "Auto" in nombre
10 // 3 en Python?// realiza división floor (división entera redondeada hacia el infinito negativo).str) son considerados inmutables?s = "hola"; s[0] = "H" resultará en un TypeError. Cualquier método de string (ej. s.upper()) retorna una *nueva* cadena.Capítulo 3 · Control de Flujo y Pattern Matching
Nivel 1 · PrincipiantePython utiliza la indentación (4 espacios por estándar PEP 8) para delimitar bloques de código. A partir de Python 3.10, la sentencia match-case provee un poderoso sistema de coincidencia de patrones estructurales.
3.1 Condicionales e Iteraciones
# Condicionales con asignación expresión ternaria estado = "Activo" if limite > 0 else "Inactivo" # Bucle for con enumerate y range usuarios = ["Alice", "Bob", "Charlie"] for indice, usuario in enumerate(usuarios, start=1): print(f"[{indice}] Procesando usuario: {usuario}") # Bucle while con cláusula else (se ejecuta si NO hubo break) intentos = 0 while intentos < 3: if conectar_servidor(): print("Conexión exitosa") break intentos += 1 else: print("Error: Máximo número de reintentos alcanzado")
3.2 Structural Pattern Matching (match-case)
Mucho más avanzado que un simple switch de C/Java; permite desestructurar diccionarios, tuplas, clases y evaluar guardas if:
def procesar_comando(comando): match comando.split(): case ["QUIT" | "EXIT"]: return "Saliendo del programa..." case ["MOVE", ("NORTH" | "SOUTH" | "EAST" | "WEST") as direccion]: return f"Moviéndose hacia {direccion}" case ["GET", item, "COUNT", int(cantidad)] if cantidad > 0: return f"Obteniendo {cantidad} unidades de {item}" case _: return "Comando no reconocido"
else asociado a un bucle for o while?else de los bucles es perfecta para búsquedas: si encuentras el elemento haces break, pero si recorres todo sin encontrarlo se ejecuta el else.Capítulo 4 · Estructuras de Datos Integradas y Comprehensions
Nivel 1 · PrincipiantePython incluye cuatro estructuras de datos coleccionables fundamentales: Listas, Tuplas, Conjuntos (Sets) y Diccionarios (Dicts).
| Estructura | Sintaxis | Ordenada | Mutable | Duplicados | Uso Principal |
|---|---|---|---|---|---|
list | [1, 2, 3] | Sí | Sí | Sí | Secuencias mutables generales |
tuple | (1, 2, 3) | Sí | No | Sí | Registros inmutables y retornos múltiples |
dict | {"a": 1} | Sí (3.7+) | Sí | Claves únicas | Mapeos clave-valor / JSON |
set | {1, 2, 3} | No | Sí | No | Filtro de duplicados y operaciones matemáticas |
4.1 Comprehensions (Comprensiones)
Permiten construir nuevas colecciones de forma concisa y altamente optimizada en código C subyacente:
# List Comprehension numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] cuadrados_pares = [x**2 for x in numeros if x % 2 == 0] # Result: [4, 16, 36, 64, 100] # Dict Comprehension estudiantes = ["Ana", "Pedro", "Maria"] notas = [95, 88, 92] mapa_notas = {est: nota for est, nota in zip(estudiantes, notas)} # Result: {'Ana': 95, 'Pedro': 88, 'Maria': 92} # Set Comprehension (Elimina duplicados automáticamente) tags = ["PYTHON", "python", "AI", "ai", "FASTAPI"] tags_limpios = {t.lower() for t in tags} # Result: {'python', 'ai', 'fastapi'}
4.2 Slicing Avanzado (Rebanado)
items = [0, 10, 20, 30, 40, 50, 60, 70] # Sintaxis: lista[inicio:fin:paso] sub_lista = items[2:6] # [20, 30, 40, 50] invertida = items[::-1] # [70, 60, 50, 40, 30, 20, 10, 0] saltos = items[::2] # [0, 20, 40, 60]
x in s) en un set de Python comparado con una list?Capítulo 5 · Funciones Avanzadas, Type Hinting y Ámbitos
Nivel 2 · IntermedioLas funciones en Python son ciudadanos de primera clase (first-class citizens), lo que significa que pueden ser asignadas a variables, pasadas como argumentos y retornadas desde otras funciones.
5.1 Parámetros Flexibles: *args, **kwargs y Posicionales Obligatorios
def crear_usuario( nombre: str, /, # Todo antes de '/' DEBE ser posicional únicamente *, # Todo después de '*' DEBE ser mediante keyword explícito email: str, rol: str = "developer", *habilidades: str, **metadatos: any ) -> dict: return { "nombre": nombre, "email": email, "rol": rol, "habilidades": habilidades, "metadatos": metadatos } # Uso correcto usr = crear_usuario("Carlos", email="carlos@autonovations.com", "Python", "Docker", departamento="AI")
list o dict por defecto (ej. def f(l=[])). Usa def f(l=None): if l is None: l = [] en su lugar.5.2 Regla de Scope LEGB (Local, Enclosing, Global, Built-in)
Python busca identificadores en cuatro niveles jerárquicos:
2. E (Enclosing): Scope de funciones anidadas contenedoras (Closure).
3. G (Global): Scope a nivel de archivo/módulo actual.
4. B (Built-in): Funciones globales de Python como print, len, range.
def procesar(datos=[]) y la llamas múltiples veces seguidas?Capítulo 6 · POO, Dunder Methods y Data Classes
Nivel 2 · IntermedioLa Programación Orientada a Objetos en Python destaca por el uso de métodos especiales rodeados de doble guion bajo (Dunder Methods / Magic Methods) y encapsulamiento idiomático mediante propiedades.
6.1 Clase Completa con Encapsulamiento y Decoradores
class CuentaBancaria: # Atributo de Clase banco = "AutoNovations Bank" def __init__(self, titular: str, saldo_inicial: float = 0.0): self.titular = titular self._saldo = saldo_inicial # Atributo protegido por convención @property def saldo(self) -> float: """Getter idiomático para saldo""" return self._saldo @saldo.setter def saldo(self, nuevo_monto: float): """Setter con validación de negocio""" if nuevo_monto < 0: raise ValueError("El saldo no puede ser negativo") self._saldo = nuevo_monto # Dunder Methods def __repr__(self) -> str: return f"CuentaBancaria(titular='{self.titular}', saldo={self._saldo})" def __eq__(self, otro) -> bool: return isinstance(otro, CuentaBancaria) and self._saldo == otro._saldo
6.2 Data Classes Moderna (@dataclass)
Disponible en el módulo estándar dataclasses; genera automáticamente __init__, __repr__, __eq__ y soporte inmutable con frozen=True:
from dataclasses import dataclass, field from datetime import datetime @dataclass(frozen=True, order=True) class Transaccion: id: str monto: float timestamp: datetime = field(default_factory=datetime.now) # Inmutable y auto-comparable tx1 = Transaccion(id="TX-101", monto=250.0) print(tx1) # Output: Transaccion(id='TX-101', monto=250.0, timestamp=datetime.datetime(...))
@property sobre los getters tradicionales tipo get_saldo()?Capítulo 7 · Manejo Robustos de Excepciones y Debugging
Nivel 2 · IntermedioEscribir código tolerante a fallos implica usar la filosofía de Python: "It's easier to ask for forgiveness than permission" (EAFP).
7.1 Bloque try-except-else-finally y Excepciones Custom
class APIError(Exception): """Excepción personalizada para servicios web""" def __init__(self, codigo: int, mensaje: str): self.codigo = codigo super().__init__(f"[{codigo}] {mensaje}") def realizar_peticion(url: str): try: # Simulación de llamada res = conectar(url) except ConnectionError as err: raise APIError(503, "Servicio no disponible") from err else: # Se ejecuta SOLO si NO hubo excepciones print("Petición procesada correctamente") return res.json() finally: # Se ejecuta SIEMPRE para liberar recursos cerrar_socket()
7.2 Debugging con breakpoint() nativo
Al invocar breakpoint() en cualquier parte del código, Python pausará la ejecución y abrirá la consola interactiva PDB (Python Debugger).
else en un bloque try-except?try, previniendo capturar excepciones accidentales.Capítulo 8 · Gestión de Archivos, Pathlib y Context Managers
Nivel 2 · IntermedioLa gestión de recursos (archivos, conexiones a bases de datos, locks) debe realizarse con la sentencia with para garantizar el cierre seguro de descriptores.
8.1 Pathlib: Manejo Moderno de Rutas
from pathlib import Path import json # Rutas orientadas a objetos multiplataforma directorio_base = Path(__file__).resolve().parent archivo_config = directorio_base / "config" / "settings.json" # Crear directorio si no existe archivo_config.parent.mkdir(parents=True, exist_ok=True) # Escritura directa datos = {"app": "AutoNovations", "version": "2026.1"} archivo_config.write_text(json.dumps(datos, indent=2), encoding="utf-8") # Lectura directa contenido = json.loads(archivo_config.read_text(encoding="utf-8"))
8.2 Crear Context Managers Custom con @contextmanager
from contextlib import contextmanager import time @contextmanager def temporizador(etiqueta: str): inicio = time.perf_counter() try: yield finally: duracion = time.perf_counter() - inicio print(f"⏱️ [{etiqueta}] Ejecutado en {duracion:.4f}s") # Uso práctico with temporizador("Carga masiva de datos"): matriz = [i**2 for i in range(1_000_000)]
with?__enter__ se ejecuta al iniciar el bloque with y su retorno se asigna a as var. __exit__ atiende la limpieza final.Capítulo 9 · Arquitectura de Módulos y Estándar pyproject.toml
Nivel 2 · IntermedioEstructurar paquetes reutilizables requiere adoptar las especificaciones PEP 621 y el archivo estandarizado pyproject.toml.
9.1 Estructura Profesional de Paquete Python
├── pyproject.toml
├── README.md
└── src/
└── mi_libreria/
├── __init__.py
├── core.py
└── utils/
├── __init__.py
└── helpers.py
9.2 pyproject.toml Estándar
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "autonovations-core"
version = "1.0.0"
description = "Librería core de utilidades para sistemas autónomos"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"pydantic>=2.7.0",
"httpx>=0.27.0",
]
[project.scripts]
auto-cli = "autonovations_core.cli:main"
pyproject.toml unifica la configuración de herramientas (ruff, pytest, mypy) y metadatos de empaquetado.Capítulo 10 · Decoradores de Alto Nivel y Generadores Memory-Efficient
Nivel 3 · AvanzadoLos decoradores permiten modificar o extender dinámicamente el comportamiento de funciones o clases sin alterar su código fuente.
10.1 Construcción de un Decorador con Parámetros y functools.wraps
from functools import wraps import time def reintentar(max_intentos: int = 3, retardo: float = 1.0): def decorador(func): @wraps(func) # Preserva el __name__ y __doc__ original def wrapper(*args, **kwargs): for intento in range(1, max_intentos + 1): try: return func(*args, **kwargs) except Exception as e: print(f"⚠️ Intento {intento}/{max_intentos} falló: {e}") if intento == max_intentos: raise time.sleep(retardo) return wrapper return decorador @reintentar(max_intentos=3, retardo=0.5) def conectar_sensor_iot(): """Simula conexión a microcontrolador""" raise ConnectionResetError("Sensor no responde")
10.2 Generadores e Iteradores de Memoria Mínima (yield)
En lugar de almacenar millones de registros en memoria RAM, las funciones generadoras devuelven un iterador perezoso (lazy evaluation) mediante yield:
def stream_telemetria_gigante(total_registros: int): for i in range(total_registros): # Genera un dato a la vez en RAM constante O(1) yield {"timestamp": time.time(), "lectura": i * 0.42} # Procesamiento streaming de 10 millones de items consumiendo < 5MB RAM for lectura in stream_telemetria_gigante(10_000_000): if lectura["lectura"] > 100: print("Alerta detectada:", lectura) break
@functools.wraps(func) al construir un decorador personalizado?Capítulo 11 · Concurrencia Avanzada y Programación Asíncrona (`asyncio`)
Nivel 3 · AvanzadoElegir el modelo de concurrencia adecuado es vital para escalar aplicaciones en Python:
| Modelo | Módulo Integrado | Ideal Para | Supera el GIL |
|---|---|---|---|
Threading | threading | Operaciones I/O intensivas simples | No (GIL activo) |
Multiprocessing | multiprocessing | Cálculo intensivo CPU (Math, ML) | Sí (Procesos separados) |
Asyncio | asyncio | I/O concurrente masivo (Web APIs, Sockets) | No (Single-thread Event Loop) |
11.1 Async / Await y asyncio.TaskGroup (Python 3.11+)
La sintaxis asyncio.TaskGroup ofrece manejo de concurrencia estructurada (structured concurrency), garantizando que si una tarea falla, las demás asociadas sean canceladas limpiamente:
import asyncio import time async def consultar_servicio(id_servicio: int, retardo: float) -> dict: await asyncio.sleep(retardo) # Cede el control al Event Loop return {"id": id_servicio, "status": "OK", "tiempo": retardo} async def main(): inicio = time.perf_counter() # Concurrencia estructurada con TaskGroup async with asyncio.TaskGroup() as tg: t1 = tg.create_task(consultar_servicio(1, 1.5)) t2 = tg.create_task(consultar_servicio(2, 0.8)) t3 = tg.create_task(consultar_servicio(3, 1.2)) # Todas las tareas finalizan aquí resultados = [t1.result(), t2.result(), t3.result()] duracion = time.perf_counter() - inicio print(f"⚡ 3 peticiones completadas en {duracion:.2f}s (en paralelo)") # Iniciar el Event Loop de asyncio asyncio.run(main())
asyncio frente a multiprocessing?Capítulo 12 · Type Hinting Avanzado (PEP 695) y Metaprogramación
Nivel 3 · AvanzadoPython 3.12 simplificó radicalmente la sintaxis de tipos genéricos mediante la palabra clave type.
12.1 Sintaxis de Tipos Genéricos de Python 3.12 (PEP 695)
# Definición de alias de tipo genérico conciso con la palabra clave type type Vector[T] = list[T] type RespuestaAPI[D] = dict[str, D | None] # Función genérica moderna sin TypeVar verboso def primero_o_defecto[T](elementos: list[T], defecto: T) -> T: return elementos[0] if elementos else defecto
12.2 Metaclases y __init_subclass__
Usa __init_subclass__ como alternativa limpia a las metaclases tradicionales para registrar subclases de forma automática:
class PluginBase: registro_plugins = {} def __init_subclass__(cls, nombre_plugin: str, **kwargs): super().__init_subclass__(**kwargs) cls.registro_plugins[nombre_plugin] = cls class PluginSQL(PluginBase, nombre_plugin="sql"): pass class PluginMongo(PluginBase, nombre_plugin="mongodb"): pass print(PluginBase.registro_plugins) # Output: {'sql':, 'mongodb': }
Capítulo 13 · Testing Profesional con Pytest y Linters Modernos (Ruff)
Nivel 3 · AvanzadoEl estándar de la industria para pruebas automatizadas en Python es pytest, complementado por herramientas ultrarrápidas de linting como Ruff.
13.1 Tests Unitarios con Fixtures y Parametrización en Pytest
import pytest # Fixture reutilizable @pytest.fixture def cliente_base_datos(): db = {"estado": "conectado", "registros": []} yield db # Setup finalizado, entrega el objeto db["registros"].clear() # Teardown de limpieza # Test parametrizado (evalúa múltiples entradas) @pytest.mark.parametrize("entrada,esperado", [ (2, 4), (5, 25), (10, 100), ]) def test_calcular_cuadrado(entrada, esperado): assert entrada ** 2 == esperado def test_insercion_db(cliente_base_datos): cliente_base_datos["registros"].append("Item 1") assert len(cliente_base_datos["registros"]) == 1
13.2 Linting Ultra Rápido con Ruff
Ruff reemplaza a flake8, black, isort y pydocstyle siendo entre 100x y 1000x más rápido al estar escrito en Rust:
uv pip install ruff pytest pytest-cov ruff check . --fix # Revisa y auto-corrige errores de código ruff format . # Formateo automático de código pytest --cov=src # Ejecuta tests con reporte de cobertura
@pytest.fixture que utiliza yield en lugar de return?Capítulo 14 · Proyectos de Producción e Integración Final
Nivel 3 · AvanzadoAplica todo lo aprendido en tres proyectos arquitectónicos completos del mundo real.
Proyecto 1 — CLI de Automatización con Typer & Rich
Stack: Typer + Rich + Pydantic
Objetivo: Desarrollar una herramienta de línea de comandos profesional con paneles de color, barras de progreso y autocompletado en shell.
import typer from rich.console import Console from rich.table import Table app = typer.Typer(help="AutoNovations CLI Tool 2026") console = Console() @app.command() def listar_servicios(region: str = "us-east-1"): """Muestra el estado de microservicios en una región""" table = Table(title=f"Estado de Servicios - {region}") table.add_column("ID", style="cyan") table.add_column("Servicio", style="white") table.add_column("Estado", style="green") table.add_row("SRV-01", "Auth Service", "HEALTHY") table.add_row("SRV-02", "AI Pipeline Engine", "HEALTHY") console.print(table) if __name__ == "__main__": app()
Proyecto 2 — API REST Asíncrona de Alto Rendimiento con FastAPI & SQLAlchemy 2.0
Stack: FastAPI + Uvicorn + Pydantic V2 + SQLAlchemy 2.0 Async + PostgreSQL
from fastapi import FastAPI, HTTPException, status from pydantic import BaseModel, EmailStr app = FastAPI(title="AutoNovations Core API", version="2026.1") class UsuarioCrear(BaseModel): nombre: str email: EmailStr edad: int @app.post("/api/v1/usuarios", status_code=status.HTTP_201_CREATED) async def crear_nuevo_usuario(usuario: UsuarioCrear): # Simulación de persistencia asíncrona if usuario.edad < 18: raise HTTPException(status_code=400, detail="Debe ser mayor de edad") return {"status": "creado", "datos": usuario}
Stack: Asyncio + HTTPX + BeautifulSoup4 + Polars + Pytest
Funcionalidades: Extracción concurrente asíncrona de 1,000+ páginas web, procesamiento ultrarrápido con Polars en lugar de Pandas, validación con Pydantic y tests automatizados en GitHub Actions.
Has completado exitosamente el curso profesional de Python 2026, dominando sintaxis moderna, arquitectura POO, type hinting, concurrencia asyncio, pytest y desarrollo de proyectos de producción.