{"id":20,"date":"2026-09-15T10:14:34","date_gmt":"2026-09-15T08:14:34","guid":{"rendered":"https:\/\/desarrollosms.com\/?p=20"},"modified":"2026-09-16T00:39:23","modified_gmt":"2026-09-15T22:39:23","slug":"python-3-15-importaciones-perezosas","status":"publish","type":"post","link":"https:\/\/desarrollosms.com\/index.php\/2026\/09\/15\/python-3-15-importaciones-perezosas\/","title":{"rendered":"Python 3.15 &#8211; acelera el arranque con importaciones perezosas"},"content":{"rendered":"<p>Python 3.15 llega el <strong>1 de octubre de 2026<\/strong> y su cambio estrella son las <strong>importaciones perezosas<\/strong> (PEP 810): una nueva palabra clave <code>lazy<\/code> que difiere la carga de un m\u00f3dulo hasta su primer uso, para acelerar el arranque de tus programas. Si alguna vez abriste un CLI de Python y contaste los segundos antes de que respondiera, esto va de eso. Aqu\u00ed vas a ver la sintaxis exacta de las importaciones perezosas en Python 3.15, c\u00f3mo se comportan en tiempo de ejecuci\u00f3n y qu\u00e9 m\u00e1s trae la versi\u00f3n.<\/p>\n<h2>Qu\u00e9 cambia con las importaciones perezosas<\/h2>\n<p>La sintaxis es una palabra clave suave, <code>lazy<\/code>, delante de la importaci\u00f3n:<\/p>\n<pre><code class=\"language-python\">lazy import json\nlazy from json import dumps<\/code><\/pre>\n<p>El m\u00f3dulo no se carga en esa l\u00ednea. Se crea un objeto proxy ligado al nombre, y el m\u00f3dulo real se carga la primera vez que usas ese nombre. Puedes comprobarlo t\u00fa mismo:<\/p>\n<pre><code class=\"language-python\">import sys\n\nlazy import json\n\nprint('json' in sys.modules)  # False - todav\u00eda no se carg\u00f3\n\n# El primer uso dispara la carga\nresultado = json.dumps({\"hola\": \"mundo\"})\n\nprint('json' in sys.modules)  # True - ahora s\u00ed<\/code><\/pre>\n<p>Con <code>lazy from<\/code>, cada nombre importado recibe su propio proxy. El primer uso de <strong>cualquiera<\/strong> de ellos carga el m\u00f3dulo completo, pero solo reifica ese nombre espec\u00edfico:<\/p>\n<pre><code class=\"language-python\">import sys\n\nlazy from json import dumps, loads\n\nprint('json' in sys.modules)  # False\n\n# Usar 'dumps' carga json y reifica SOLO 'dumps'\nresultado = dumps({\"hola\": \"mundo\"})\nprint('json' in sys.modules)  # True\n\n# Acceder a 'loads' ahora lo reifica (json ya est\u00e1 cargado)\ndatos = loads(resultado)<\/code><\/pre>\n<p>Un matiz importante: la importaci\u00f3n perezosa difiere <strong>cu\u00e1ndo<\/strong> se carga un m\u00f3dulo, no <strong>qu\u00e9<\/strong> se carga. Cuando el proxy se resuelve, el m\u00f3dulo entero se ejecuta igual que siempre.<\/p>\n<h2>Las reglas y los l\u00edmites<\/h2>\n<p>Antes de usarlas en tu proyecto, conoce las restricciones de la PEP 810:<\/p>\n<ul>\n<li>Solo funcionan a nivel de m\u00f3dulo. Dentro de funciones, cuerpos de clase o bloques <code>try<\/code> son un error de sintaxis.<\/li>\n<li>Las star imports no se permiten: <code>lazy from json import *<\/code> no compila.<\/li>\n<li><code>lazy from __future__ import ...<\/code> tampoco existe.<\/li>\n<li>Como <code>lazy<\/code> es una palabra clave <strong>suave<\/strong>, sigue funcionando como nombre de variable en cualquier otro contexto \u2014 solo tiene significado especial justo antes de un <code>import<\/code>.<\/li>\n<\/ul>\n<p>Los errores tambi\u00e9n se comportan distinto, y esto conviene saberlo antes de que te sorprenda en producci\u00f3n:<\/p>\n<ul>\n<li>Un m\u00f3dulo que no existe ya no falla en la l\u00ednea del import, falla en el <strong>primer uso<\/strong> \u2014 con un traceback encadenado que muestra tanto la l\u00ednea del import como la l\u00ednea que lo dispar\u00f3.<\/li>\n<li>Un fallo no envenena el proxy: los accesos posteriores reintentan la importaci\u00f3n.<\/li>\n<li>Despu\u00e9s de unos accesos, el int\u00e9rprete adapta el bytecode y el costo se vuelve pr\u00e1cticamente cero. Un import reificado es indistinguible de uno normal.<\/li>\n<\/ul>\n<h2>C\u00f3mo afecta a tu c\u00f3digo existente<\/h2>\n<p>Es un cambio <strong>opt-in<\/strong>: no tocas nada y tu c\u00f3digo funciona igual. Pero si adoptas <code>lazy<\/code>, hay consecuencias pr\u00e1cticas que revisar:<\/p>\n<ul>\n<li><strong>Tus imports dejan de ser tu primera l\u00ednea de defensa.<\/strong> Si ten\u00edas un import en la cabecera para validar que una dependencia existe, con <code>lazy<\/code> el fallo se mueve al primer uso \u2014 posiblemente en un path que tus tests no cubren.<\/li>\n<li><strong>Los CLIs ganan lo m\u00e1s.<\/strong> El caso de uso que motiv\u00f3 la PEP: herramientas de l\u00ednea de comandos que importan librer\u00edas pesadas que solo se necesitan en algunas rutas. Diferir la carga es arranque m\u00e1s r\u00e1pido para todos.<\/li>\n<li><strong>El import circular que estabas escondiendo puede aparecer.<\/strong> Si difer\u00edas un import dentro de una funci\u00f3n precisamente por una dependencia circular, ahora tienes una herramienta de primera clase para eso \u2014 \u00fasala sabiendo que es lo que est\u00e1s haciendo.<\/li>\n<\/ul>\n<p>Para probarlo hoy sin tocar tu versi\u00f3n del sistema, instala el candidato (no lo uses en producci\u00f3n todav\u00eda):<\/p>\n<pre><code class=\"language-bash\">pyenv install 3.15.0rc2\npyenv local 3.15.0rc2<\/code><\/pre>\n<h2>Lo dem\u00e1s que trae Python 3.15<\/h2>\n<p>Las importaciones perezosas son el titular, pero no vienen solas:<\/p>\n<ul>\n<li><strong>frozendict (PEP 814)<\/strong>: un diccionario inmutable como tipo integrado \u2014 el equivalente de <code>frozenset<\/code> para dicts, \u00fatil como constante compartida y clave de otro dict.<\/li>\n<li><strong>sentinel (PEP 661)<\/strong>: un tipo para valores centinela, para dejar de inventar <code>object()<\/code> como marcador de \u00absin valor\u00bb.<\/li>\n<li><strong>Tachyon (PEP 799)<\/strong>: un profiler estad\u00edstico de alta frecuencia integrado, dentro de un paquete dedicado a organizar las herramientas de profiling.<\/li>\n<li><strong>UTF-8 por defecto (PEP 686)<\/strong>: Python deja de depender de la configuraci\u00f3n regional para la codificaci\u00f3n. Si trabajas con archivos en Latin-1 heredados, rev\u00edsalo antes de migrar.<\/li>\n<li><strong>JIT m\u00e1s r\u00e1pido<\/strong>: 8-9% de mejora geom\u00e9trica en Linux x86-64 y 12-13% en macOS AArch64 sobre el int\u00e9rprete est\u00e1ndar.<\/li>\n<li><strong>Punteros de frame activados por defecto (PEP 831)<\/strong>: mejor observabilidad para profilers y herramientas de diagn\u00f3stico.<\/li>\n<\/ul>\n<h2>C\u00f3mo comprobar que lo aprovechas<\/h2>\n<p>Un ejercicio honesto antes de sembrar <code>lazy<\/code> por todo tu c\u00f3digo: mide. Arranca tu programa con un perfil de arranque \u2014 el propio Tachyon sirve \u2014 anota cu\u00e1nto tarda, aplica <code>lazy<\/code> a las importaciones pesadas que no se usan en el camino principal, y vuelve a medir. Si la mejora no se ve, no la uses ah\u00ed: el costo de legibilidad debe comprar algo real.<\/p>\n<p>Fuentes: el <a href=\"https:\/\/blog.python.org\/2026\/09\/python-3150-rc2\/\" target=\"_blank\" rel=\"noopener\">anuncio de la RC2 en blog.python.org<\/a> y la <a href=\"https:\/\/peps.python.org\/pep-0810\/\" target=\"_blank\" rel=\"noopener\">PEP 810 completa<\/a> con la especificaci\u00f3n de la sintaxis.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Python 3.15 llega el 1 de octubre con importaciones perezosas (PEP 810), frozendict, sentinel y el profiler Tachyon. C\u00f3mo funciona lazy import y qu\u00e9 cambia en tu c\u00f3digo.<\/p>\n","protected":false},"author":2,"featured_media":36,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[12,13],"class_list":["post-20","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacion","tag-python","tag-rendimiento"],"_links":{"self":[{"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/posts\/20","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/comments?post=20"}],"version-history":[{"count":1,"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/posts\/20\/revisions"}],"predecessor-version":[{"id":29,"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/posts\/20\/revisions\/29"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/media\/36"}],"wp:attachment":[{"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/media?parent=20"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/categories?post=20"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/desarrollosms.com\/index.php\/wp-json\/wp\/v2\/tags?post=20"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}