Novedades de Python 3.15: Importaciones diferidas explícitas y frozendict nativo para un salto de rendimiento

Python · Release 3.15

Novedades de Python 3.15: Importaciones diferidas explícitas y frozendict nativo para un salto de rendimiento

pythonPythonLanzamientoImportaciones DiferidasfrozendictOptimización de Rendimiento

Fuentes:GitHub Releases + 官方博客 + HN

Python 3.15 se publicó oficialmente el 9 de octubre de 2026. Esta versión aporta mejoras sustanciales tanto en la sintaxis del lenguaje como en la optimización del rendimiento. Las importaciones diferidas explícitas (lazy imports) resuelven el cuello de botella del arranque lento en aplicaciones de gran tamaño, la incorporación de frozendict cubre la histórica necesidad de mapeos inmutables, el desempaquetado en comprensiones simplifica el código de transformación y la introducción de una ABI estable para compilaciones libres de hilos (free-threaded) consolida el camino hacia la concurrencia multinúcleo. Analizamos a continuación las novedades más destacadas de este lanzamiento.

PEP 810: Importaciones diferidas explícitas (Explicit lazy imports)

Las aplicaciones Python de gran envergadura suelen experimentar tiempos de inicio lentos debido a la importación en cascada de dependencias. Tradicionalmente, los desarrolladores postergaban las sentencias import dentro de funciones o recurrían a importlib para cargarlas bajo demanda. Python 3.15 ofrece una solución nativa y más elegante: importaciones diferidas explícitas mediante la palabra clave contextual lazy.

Al utilizar lazy import, Python no carga el módulo de inmediato, sino que crea un objeto proxy ligero. La carga real no tiene lugar hasta que se accede por primera vez a un atributo o nombre de dicho módulo.

lazy import json
lazy from pathlib import Path

print("Starting up...")  # json y pathlib aún no se han importado por completo

data = json.loads('{"key": "value"}')  # Solo en este acceso se importa json por completo
p = Path(".")  # Solo en este acceso se importa pathlib por completo

Si el módulo importado de forma diferida no existe, la excepción se lanzará en el momento del primer acceso. Los desarrolladores también pueden controlar este comportamiento de manera global a través de la variable de entorno PYTHON_LAZY_IMPORTS o la opción de línea de comandos -X lazy_imports.

PEP 814: Nuevo tipo integrado frozendict

Python 3.15 añade frozendict, un nuevo tipo de mapeo inmutable integrado en el lenguaje. Hereda directamente de object y no es una subclase de dict. Siempre que todas sus claves y valores sean procesables por hash (hashable), el propio frozendict también lo será. frozendict conserva el orden de inserción, aunque este se ignora al realizar comparaciones de igualdad (==).

Su llegada facilita enormemente el manejo de mapeos inmutables, especialmente al utilizarlos como claves en diccionarios o elementos en conjuntos.

>>> a = frozendict(x=1, y=2)
>>> a
frozendict({'x': 1, 'y': 2})
>>> a['z'] = 3
Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
    a['z'] = 3
    ~^^^^^
TypeError: 'frozendict' object does not support item assignment
>>> b = frozendict(y=2, x=1)
>>> hash(a) == hash(b)
True
>>> a == b
True

PEP 798: Desempaquetado en comprensiones (Unpacking in comprehensions)

Las comprensiones de listas, conjuntos y diccionarios, así como las expresiones generadoras, admiten ahora el desempaquetado mediante * y **. Esta mejora constituye una extensión natural de la sintaxis introducida en el PEP 448, permitiendo aplanar múltiples iterables o fusionar diccionarios en una estructura única sin necesidad de comprensiones anidadas ni de itertools.chain().

>>> lists = [[1, 2], [3, 4], [5]]
>>> [*L for L in lists]  # Equivalente a [x for L in lists for x in L]
[1, 2, 3, 4, 5]

>>> sets = [{1, 2}, {2, 3}, {3, 4}]
>>> {*s for s in sets}  # Equivalente a {x for s in sets for x in s}
{1, 2, 3, 4}

>>> dicts = [{'a': 1}, {'b': 2}, {'a': 3}]
>>> {**d for d in dicts}  # Equivalente a {k: v for d in dicts for k,v in d.items()}
{'a': 3, 'b': 2}

Las expresiones generadoras siguen exactamente el mismo principio:

>>> gen = (*L for L in lists)  # Equivalente a (x for L in lists for x in L)
>>> list(gen)
[1, 2, 3, 4, 5]

PEP 661: Nuevo tipo integrado sentinel

Python 3.15 añade el tipo sentinel al módulo builtins, ofreciendo una fórmula estandarizada para definir valores centinela únicos con representaciones limpias. Los objetos centinela conservan su identidad en copias superficiales, admiten el operador de unión | en expresiones de tipo y pueden serializarse con pickle si son importables mediante módulo y nombre.

PEP 803: ABI estable para compilaciones sin GIL (abi3t)

Para las compilaciones de Python con soporte multihilo sin GIL (free-threaded), las extensiones en C pueden compilarse ahora contra una nueva ABI estable denominada abi3t. Adoptar abi3t requiere ajustar el código fuente para usar las API de PEP 697 y el nuevo hook de exportación de módulos PyModExport_* introducido en PEP 793.

Las extensiones que no puedan migrar inmediatamente a abi3t deben continuar generando compilaciones separadas para la ABI estable convencional (abi3) y para la ABI específica de la versión sin GIL (cp315t).

Recomendaciones y consideraciones de actualización

CriterioDescripción detallada
Quién debería actualizarDesarrolladores de aplicaciones de gran escala que requieran arranques rápidos; desarrolladores con operaciones complejas de combinación de diccionarios; mantenedores de librerías que adapten activamente extensiones en C a entornos multihilo sin GIL.
Cuándo actualizarPuede comenzar a probar Python 3.15 de inmediato en entornos de desarrollo local y pruebas. Para producción, se recomienda esperar a que las dependencias críticas (especialmente extensiones en C) ofrezcan soporte para abi3t o cp315t.
Puntos de atención• Las funciones de rastreo de cProfile se integran en el nuevo módulo profiling (PEP 799).
• El módulo heredado profile queda en desuso y se eliminará en Python 3.17.
• Las sentencias import en archivos .pth quedan en desuso de forma silenciosa, recomendándose los nuevos archivos de configuración .start (PEP 829).
• La familia de API PyGILState entra en desuso suave (soft-deprecated) y no recibirá más añadidos (PEP 788).

Fuentes de referencia