<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Python · DacaCode &lt;/&gt;</title><link>https://blog.dacadev.com/categories/python/</link><description>Blog de tecnología, programación y electrónica, para compartir conocimientos, experiencias y tutoriales con este apasionante mundo.</description><generator>Hugo</generator><language>es-CO</language><copyright>Copyright © 2026 DacaDev. All rights reserved.</copyright><lastBuildDate>Wed, 13 May 2026 00:00:00 -0500</lastBuildDate><atom:link href="https://blog.dacadev.com/categories/python/index.xml" rel="self" type="application/rss+xml"/><image><url>https://blog.dacadev.com/images/blog-logo.png</url><title>DacaCode &lt;/&gt;</title><link>https://blog.dacadev.com/</link></image><item><title>Futures, Awaitables y Errores Comunes en asyncio</title><link>https://blog.dacadev.com/python/asyncio/futures-awaitables-errores-comunes/</link><pubDate>Wed, 13 May 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/asyncio/futures-awaitables-errores-comunes/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Entiende qué son los futures y awaitables en asyncio, cómo medir el rendimiento de código asíncrono y los errores más comunes que bloquean el event loop en Python.</description><media:content url="https://blog.dacadev.com/images/python/asyncio/futures-awaitables/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#futures-un-valor-que-aún-no-existe"&gt;Futures: Un Valor que Aún No Existe&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#futures-en-la-práctica"&gt;Futures en la práctica&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#la-jerarquía-de-los-awaitables"&gt;La Jerarquía de los Awaitables&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#midiendo-el-tiempo-de-ejecución"&gt;Midiendo el Tiempo de Ejecución&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#uso-en-la-práctica"&gt;Uso en la práctica&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#errores-comunes-en-asyncio"&gt;Errores Comunes en &lt;code&gt;asyncio&lt;/code&gt;&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#1-ejecutar-código-cpu-bound-en-coroutines"&gt;1. Ejecutar código CPU-bound en coroutines&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#2-usar-apis-bloqueantes"&gt;2. Usar APIs bloqueantes&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#en-conclusión"&gt;En conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#referencias"&gt;Referencias&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;En los artículos anteriores aprendimos a crear &lt;a href="https://blog.dacadev.com/python/asyncio/coroutines-async-await"



 


&gt;coroutines con async/await&lt;/a&gt; y ejecutar tasks concurrentes. En este artículo vamos a cerrar el modelo mental: entenderemos qué son los &lt;strong&gt;futures&lt;/strong&gt;, cómo se relacionan con tasks y coroutines a través de los &lt;strong&gt;awaitables&lt;/strong&gt;, y veremos cómo medir el rendimiento de nuestro código asíncrono. Para cerrar, hablaremos de los dos errores más comunes al trabajar con &lt;code&gt;asyncio&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="futures-un-valor-que-aún-no-existe"&gt;Futures: Un Valor que Aún No Existe&lt;/h2&gt;
&lt;p&gt;Un &lt;strong&gt;future&lt;/strong&gt; es un objeto de Python que representa un valor que esperamos obtener en algún momento, pero que &lt;strong&gt;todavía no tenemos&lt;/strong&gt;. Cuando se crea, un future está en estado &lt;em&gt;incompleto&lt;/em&gt;. Una vez que el valor llega, se establece con &lt;code&gt;set_result&lt;/code&gt; y el future pasa a estar &lt;em&gt;completado&lt;/em&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Future&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;my_future&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Future&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;¿Está completo? &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;my_future&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;done&lt;/span&gt;()&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;my_future&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;set_result&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;42&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;¿Está completo? &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;my_future&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;done&lt;/span&gt;()&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Resultado: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;my_future&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;result&lt;/span&gt;()&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre class="mermaid"&gt;stateDiagram-v2
 [*] --&gt; Incompleto: Future()
 Incompleto --&gt; Completado: set_result(valor)
 Completado --&gt; [*]: result() → valor

 note right of Incompleto
 done() → False
 result() → InvalidStateError
 end note

 note right of Completado
 done() → True
 result() → valor
 end note
&lt;/pre&gt;

&lt;h3 id="futures-en-la-práctica"&gt;Futures en la práctica&lt;/h3&gt;
&lt;p&gt;En la mayoría de los casos no crearás futures directamente — &lt;code&gt;asyncio&lt;/code&gt; los gestiona internamente. Pero entender su mecánica es clave para comprender cómo funciona todo por dentro. Veamos un ejemplo donde un task establece el valor de un future después de un segundo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Future&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;hacer_peticion&lt;/span&gt;() &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Future&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;future&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Future&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_task&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;establecer_valor&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;future&lt;/span&gt;)) &lt;span style="color:#7f848e"&gt;# 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;future&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;establecer_valor&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;future&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;future&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;set_result&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;42&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;main&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;future&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;hacer_peticion&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;¿Está completo? &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;future&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;done&lt;/span&gt;()&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;valor&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;future&lt;/span&gt; &lt;span style="color:#7f848e"&gt;# 3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;¿Está completo? &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;future&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;done&lt;/span&gt;()&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;valor&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;run&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;main&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;
&lt;li&gt;Crea un task que configurará el valor del future.&lt;/li&gt;
&lt;li&gt;Espera 1 segundo antes de establecer el resultado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;await&lt;/code&gt; pausa &lt;code&gt;main()&lt;/code&gt; hasta que el future reciba su valor.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 participant M as main()
 participant F as Future
 participant T as task: establecer_valor()

 M-&gt;&gt;F: hacer_peticion() → Future incompleto
 M-&gt;&gt;T: create_task(establecer_valor(future))
 M-&gt;&gt;F: await future
 Note over M: ⏸ PAUSE main()
 T-&gt;&gt;T: await asyncio.sleep(1)
 Note over T: ⏳ 1 segundo...
 T-&gt;&gt;F: set_result(42)
 Note over F: ✅ Completado
 F--&gt;&gt;M: ▶ RESUME main()
 Note over M: valor = 42
&lt;/pre&gt;

&lt;h2 id="la-jerarquía-de-los-awaitables"&gt;La Jerarquía de los Awaitables&lt;/h2&gt;
&lt;p&gt;Tanto las coroutines como los tasks pueden usarse con &lt;code&gt;await&lt;/code&gt;. ¿Qué tienen en común? Ambos son &lt;strong&gt;awaitables&lt;/strong&gt; — objetos que implementan el método &lt;code&gt;__await__&lt;/code&gt;, que es lo que Python necesita para poder usar la palabra clave &lt;code&gt;await&lt;/code&gt; sobre ellos.&lt;/p&gt;
&lt;p&gt;La relación entre estos conceptos forma una jerarquía clara:&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 A["Awaitable\n(__await__)"] --&gt; B["Coroutine"]
 A --&gt; C["Future"]
 C --&gt; D["Task"]

 style A fill:#8b5cf6,stroke:#5b21b6,color:#fff
 style B fill:#3b82f6,stroke:#1e40af,color:#fff
 style C fill:#f59e0b,stroke:#b45309,color:#fff
 style D fill:#10b981,stroke:#065f46,color:#fff
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Awaitable&lt;/strong&gt; es la clase base que define el protocolo &lt;code&gt;__await__&lt;/code&gt;. Todo lo que se pueda usar con &lt;code&gt;await&lt;/code&gt; es un awaitable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coroutine&lt;/strong&gt; es una función definida con &lt;code&gt;async def&lt;/code&gt;. Hereda de &lt;code&gt;Awaitable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Future&lt;/strong&gt; representa un valor pendiente. También hereda de &lt;code&gt;Awaitable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Task&lt;/strong&gt; hereda de &lt;code&gt;Future&lt;/code&gt;. Es la combinación de un future y una coroutine: encapsula una coroutine y la ejecuta en el event loop, mientras que el future subyacente almacena el resultado cuando la coroutine termina.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Un &lt;strong&gt;Future&lt;/strong&gt; es &lt;em&gt;qué&lt;/em&gt; esperamos obtener. Un &lt;strong&gt;Task&lt;/strong&gt; es &lt;em&gt;cómo&lt;/em&gt; lo obtenemos (ejecutando una coroutine). Y &lt;strong&gt;Awaitable&lt;/strong&gt; es el contrato que ambos cumplen para que &lt;code&gt;await&lt;/code&gt; funcione.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="midiendo-el-tiempo-de-ejecución"&gt;Midiendo el Tiempo de Ejecución&lt;/h2&gt;
&lt;p&gt;Cuando trabajamos con código asíncrono, medir cuánto tarda cada operación es esencial para verificar que la concurrencia realmente funciona. La mejor forma de hacerlo es con un &lt;strong&gt;decorador&lt;/strong&gt; que registre el tiempo de inicio y fin de cada coroutine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;functools&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Callable&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Any&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;async_timed&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;wrapper&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;func&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Callable&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Callable&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#61afef"&gt;@functools.wraps&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;func&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;wrapped&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;&lt;span style="color:#e06c75"&gt;args&lt;/span&gt;, &lt;span style="color:#56b6c2"&gt;**&lt;/span&gt;&lt;span style="color:#e06c75"&gt;kwargs&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Any&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;starting &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;func&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; with args &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;args&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;kwargs&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;start&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;time&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;time&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;try&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;func&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;&lt;span style="color:#e06c75"&gt;args&lt;/span&gt;, &lt;span style="color:#56b6c2"&gt;**&lt;/span&gt;&lt;span style="color:#e06c75"&gt;kwargs&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;finally&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;end&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;time&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;time&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;total&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;end&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;-&lt;/span&gt; &lt;span style="color:#e06c75"&gt;start&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;finished &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;func&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; in &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;total&lt;/span&gt;&lt;span style="color:#98c379"&gt;:&lt;/span&gt;&lt;span style="color:#98c379"&gt;.4f&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; second(s)&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;wrapped&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;wrapper&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="uso-en-la-práctica"&gt;Uso en la práctica&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#61afef"&gt;@async_timed&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;delay&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;delay_seconds&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;sleeping for &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;delay_seconds&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; second(s)&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;delay_seconds&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;finished sleeping for &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;delay_seconds&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; second(s)&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;delay_seconds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#61afef"&gt;@async_timed&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;main&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;task_one&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_task&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;delay&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;task_two&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;create_task&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;delay&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;3&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;task_one&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;task_two&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;run&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;main&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;starting &amp;lt;function main ...&amp;gt; with args () {}
starting &amp;lt;function delay ...&amp;gt; with args (2,) {}
starting &amp;lt;function delay ...&amp;gt; with args (3,) {}
finished &amp;lt;function delay ...&amp;gt; in 2.0032 second(s)
finished &amp;lt;function delay ...&amp;gt; in 3.0003 second(s)
finished &amp;lt;function main ...&amp;gt; in 3.0004 second(s)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;El output confirma lo que esperamos: ambos tasks corren concurrentemente. &lt;code&gt;delay(2)&lt;/code&gt; termina a los ~2 segundos, &lt;code&gt;delay(3)&lt;/code&gt; a los ~3, y &lt;code&gt;main()&lt;/code&gt; tarda ~3 segundos en total (no 5).&lt;/p&gt;
&lt;pre class="mermaid"&gt;gantt
 title Ejecución concurrente verificada con @async_timed
 dateFormat X
 axisFormat %s

 section delay(2)
 sleep(2) :a1, 0, 2

 section delay(3)
 sleep(3) :b1, 0, 3

 section main()
 Tiempo total :c1, 0, 3
&lt;/pre&gt;

&lt;h2 id="errores-comunes-en-asyncio"&gt;Errores Comunes en &lt;code&gt;asyncio&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Hay dos trampas frecuentes que pueden arruinar el rendimiento de una aplicación async. Ambas tienen la misma causa: &lt;strong&gt;bloquear el event loop&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="1-ejecutar-código-cpu-bound-en-coroutines"&gt;1. Ejecutar código CPU-bound en coroutines&lt;/h3&gt;
&lt;p&gt;Cuando tenemos funciones computacionalmente costosas (cálculos matemáticos, procesamiento de datos grandes), puede parecer buena idea envolverlas en tasks para ejecutarlas concurrentemente. Pero recuerda: &lt;code&gt;asyncio&lt;/code&gt; usa &lt;strong&gt;un solo hilo&lt;/strong&gt;. El GIL garantiza que solo una instrucción de bytecode se ejecute a la vez, así que el código CPU-bound bloqueará el event loop sin importar cuántos tasks crees.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A["Código CPU-bound\nen una coroutine"] --&gt;|"Bloquea el\nevent loop 🛑"| B["Otras tareas\nno pueden ejecutarse"]
 C["Solución"] --&gt; D["multiprocessing\no run_in_executor()"]

 style A fill:#ef4444,stroke:#991b1b,color:#fff
 style B fill:#ef4444,stroke:#991b1b,color:#fff
 style D fill:#10b981,stroke:#065f46,color:#fff
&lt;/pre&gt;

&lt;h3 id="2-usar-apis-bloqueantes"&gt;2. Usar APIs bloqueantes&lt;/h3&gt;
&lt;p&gt;El mismo problema ocurre al usar librerías de I/O que no son asíncronas. Librerías como &lt;code&gt;requests&lt;/code&gt; o funciones como &lt;code&gt;time.sleep&lt;/code&gt; bloquean el hilo principal. Cuando las llamas dentro de una coroutine, &lt;strong&gt;bloqueas el event loop completo&lt;/strong&gt; y ninguna otra coroutine puede ejecutarse.&lt;/p&gt;



&lt;div class="tab" data-tab-group=""&gt;
 &lt;ul class="tab-nav" data-tab-nav&gt;
 
 &lt;li
 class="tab-nav-item active"
 data-tab="bloqueante" tabindex="0"&gt;
 ❌ Bloqueante
 &lt;/li&gt;
 
 &lt;li
 class="tab-nav-item "
 data-tab="no-bloqueante" tabindex="-1"&gt;
 ✅ No bloqueante
 &lt;/li&gt;
 
 &lt;/ul&gt;
 &lt;div class="tab-content" data-tab-content&gt;
 
 &lt;div
 class="tab-content-panel active"
 data-tab-panel="bloqueante"&gt;
 &lt;h4 id="no-uses-estas-funciones-dentro-de-coroutines"&gt;No uses estas funciones dentro de coroutines&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;requests.get()&lt;/code&gt; → bloquea el event loop&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time.sleep()&lt;/code&gt; → bloquea el event loop&lt;/li&gt;
&lt;li&gt;Cualquier función de I/O síncrona&lt;/li&gt;
&lt;/ul&gt;

 &lt;/div&gt;
 
 &lt;div
 class="tab-content-panel "
 data-tab-panel="no-bloqueante"&gt;
 &lt;h4 id="usa-las-alternativas-asíncronas"&gt;Usa las alternativas asíncronas&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aiohttp.org/"




 target="_blank"
 


&gt;&lt;code&gt;aiohttp&lt;/code&gt;&lt;/a&gt; → reemplazo async de &lt;code&gt;requests&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;asyncio.sleep()&lt;/code&gt; → cede control al event loop&lt;/li&gt;
&lt;li&gt;&lt;a href="https://magicstack.github.io/asyncpg/"




 target="_blank"
 


&gt;&lt;code&gt;asyncpg&lt;/code&gt;&lt;/a&gt; → cliente async de PostgreSQL&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Tinche/aiofiles"




 target="_blank"
 


&gt;&lt;code&gt;aiofiles&lt;/code&gt;&lt;/a&gt; → lectura/escritura async de archivos&lt;/li&gt;
&lt;/ul&gt;

 &lt;/div&gt;
 
 &lt;/div&gt;
&lt;/div&gt;





 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;strong&gt;Regla general:&lt;/strong&gt; cualquier función que realice I/O y no sea una coroutine, o que ejecute operaciones CPU costosas, debe considerarse bloqueante. Para CPU-bound, usa &lt;a href="https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor"




 target="_blank"
 


&gt;&lt;code&gt;loop.run_in_executor()&lt;/code&gt;&lt;/a&gt; con un &lt;code&gt;ProcessPoolExecutor&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="en-conclusión"&gt;En conclusión&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;Future&lt;/strong&gt; representa un valor que aún no existe — se completa con &lt;code&gt;set_result&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Un &lt;strong&gt;Task&lt;/strong&gt; es un future + una coroutine: ejecuta la coroutine y almacena su resultado en el future subyacente.&lt;/li&gt;
&lt;li&gt;Todo lo que se pueda usar con &lt;code&gt;await&lt;/code&gt; es un &lt;strong&gt;Awaitable&lt;/strong&gt; — el contrato que unifica coroutines, futures y tasks.&lt;/li&gt;
&lt;li&gt;El decorador &lt;code&gt;@async_timed&lt;/code&gt; permite verificar que la concurrencia funciona midiendo tiempos reales.&lt;/li&gt;
&lt;li&gt;Los dos errores más comunes son ejecutar &lt;strong&gt;código CPU-bound&lt;/strong&gt; y usar &lt;strong&gt;APIs bloqueantes&lt;/strong&gt; dentro de coroutines — ambos bloquean el event loop.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="referencias"&gt;Referencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/asyncio-future.html"




 target="_blank"
 


&gt;Python &lt;code&gt;asyncio.Future&lt;/code&gt; — Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/asyncio-task.html#asyncio.Task"




 target="_blank"
 


&gt;Python &lt;code&gt;asyncio.Task&lt;/code&gt; — Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/reference/datamodel.html#awaitable-objects"




 target="_blank"
 


&gt;Python Data Model — Awaitables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://realpython.com/async-io-python/"




 target="_blank"
 


&gt;Real Python — Async IO in Python: A Complete Walkthrough&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://peps.python.org/pep-3156/"




 target="_blank"
 


&gt;PEP 3156 — Asynchronous IO Support Rebooted&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Coroutines y async/await: Tu Primer Código Asíncrono en Python</title><link>https://blog.dacadev.com/python/asyncio/coroutines-async-await/</link><pubDate>Tue, 12 May 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/asyncio/coroutines-async-await/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Aprende a crear coroutines con async def, pausar la ejecución con await, usar asyncio.run y evitar la trampa del await secuencial en Python.</description><media:content url="https://blog.dacadev.com/images/python/asyncio/coroutines-async-await/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-una-coroutine"&gt;¿Qué es una Coroutine?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#creando-coroutines"&gt;Creando Coroutines&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#ejecutando-coroutines-con-asynciorun"&gt;Ejecutando Coroutines con &lt;code&gt;asyncio.run&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#pausando-la-ejecución-con-await"&gt;Pausando la Ejecución con &lt;code&gt;await&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#simulando-operaciones-largas-con-asynciosleep"&gt;Simulando Operaciones Largas con &lt;code&gt;asyncio.sleep&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#la-trampa-del-await-secuencial"&gt;La Trampa del &lt;code&gt;await&lt;/code&gt; Secuencial&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#el-problema-visualizado"&gt;El problema visualizado&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#cómo-logramos-concurrencia-real"&gt;¿Cómo logramos concurrencia real?&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#en-conclusión"&gt;En conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#referencias"&gt;Referencias&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;En los artículos anteriores construimos la base teórica: &lt;a href="https://blog.dacadev.com/python/asyncio/fundamentos-asyncio"



 


&gt;concurrencia vs paralelismo&lt;/a&gt;, &lt;a href="https://blog.dacadev.com/python/asyncio/procesos-hilos-event-loop"



 


&gt;procesos, hilos, el GIL y el event loop&lt;/a&gt;. Ahora es momento de escribir código. En este artículo vamos a aprender a crear &lt;strong&gt;coroutines&lt;/strong&gt;, usar las palabras clave &lt;code&gt;async&lt;/code&gt; y &lt;code&gt;await&lt;/code&gt;, y entender exactamente qué pasa cuando pausamos y reanudamos la ejecución.&lt;/p&gt;
&lt;h2 id="qué-es-una-coroutine"&gt;¿Qué es una Coroutine?&lt;/h2&gt;
&lt;p&gt;Una coroutine es como una función normal de Python, pero con un superpoder: &lt;strong&gt;puede pausar su ejecución&lt;/strong&gt; cuando encuentra una operación que podría tardar (una petición de red, una lectura de disco, una espera). Mientras la coroutine está pausada, el event loop puede ejecutar otras tareas. Cuando la operación termina, la coroutine se &amp;ldquo;despierta&amp;rdquo; y continúa desde donde se detuvo.&lt;/p&gt;
&lt;p&gt;Esta capacidad de pausar y reanudar es lo que le da concurrencia a nuestra aplicación.&lt;/p&gt;
&lt;p&gt;Para trabajar con coroutines necesitamos dos palabras clave:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;async def&lt;/code&gt;&lt;/strong&gt; → define una coroutine.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; → pausa la coroutine hasta que la operación esperada termine.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="creando-coroutines"&gt;Creando Coroutines&lt;/h2&gt;
&lt;p&gt;Crear una coroutine es casi idéntico a crear una función normal. La única diferencia es usar &lt;code&gt;async def&lt;/code&gt; en lugar de &lt;code&gt;def&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;mi_coroutine&lt;/span&gt;() &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;¡Hola mundo!&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;strong&gt;Llamar a una coroutine no la ejecuta.&lt;/strong&gt; Solo produce un objeto coroutine. Para ejecutarla, necesitas un event loop.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# ❌ Esto NO ejecuta la coroutine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;mi_coroutine&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;# Retorna un objeto coroutine, no imprime nada&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# ✅ Esto SÍ la ejecuta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;run&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;mi_coroutine&lt;/span&gt;()) &lt;span style="color:#7f848e"&gt;# Imprime: ¡Hola mundo!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ejecutando-coroutines-con-asynciorun"&gt;Ejecutando Coroutines con &lt;code&gt;asyncio.run&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;asyncio.run&lt;/code&gt; es el &lt;strong&gt;punto de entrada principal&lt;/strong&gt; de cualquier aplicación asyncio. Veamos un ejemplo concreto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;sumar_uno&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;numero&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;resultado&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;run&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;sumar_uno&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;resultado&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;asyncio.run&lt;/code&gt; hace varias cosas por nosotros:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Crea&lt;/strong&gt; un event loop nuevo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ejecuta&lt;/strong&gt; la coroutine que le pasamos hasta que se completa.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retorna&lt;/strong&gt; el resultado de la coroutine.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limpia&lt;/strong&gt; cualquier tarea pendiente y cierra el event loop.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A["asyncio.run(coroutine)"] --&gt; B["Crea el\nEvent Loop"]
 B --&gt; C["Ejecuta la\ncoroutine"]
 C --&gt; D["Retorna\nel resultado"]
 D --&gt; E["Cierra el\nEvent Loop"]

 style A fill:#3b82f6,stroke:#1e40af,color:#fff
 style C fill:#10b981,stroke:#065f46,color:#fff
 style E fill:#64748b,stroke:#334155,color:#fff
&lt;/pre&gt;





 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;asyncio.run&lt;/code&gt; está diseñado para ejecutarse &lt;strong&gt;una sola vez&lt;/strong&gt; como entrada principal de tu aplicación. Esa única coroutine debería encargarse de lanzar todas las demás tareas.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="pausando-la-ejecución-con-await"&gt;Pausando la Ejecución con &lt;code&gt;await&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;El verdadero poder de asyncio está en &lt;code&gt;await&lt;/code&gt;. Esta palabra clave hace dos cosas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ejecuta&lt;/strong&gt; la coroutine que le sigue (a diferencia de llamarla directamente, que solo crea el objeto).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pausa&lt;/strong&gt; la coroutine contenedora hasta que la coroutine esperada retorne un resultado.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cuando la coroutine esperada termina, la coroutine contenedora se &amp;ldquo;despierta&amp;rdquo; y puede usar el resultado.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;obtener_saludo&lt;/span&gt;() &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;¡Hola desde una coroutine!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;main&lt;/span&gt;() &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;saludo&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;obtener_saludo&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;# Pausa main() hasta obtener el resultado&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;saludo&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;run&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;main&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="simulando-operaciones-largas-con-asynciosleep"&gt;Simulando Operaciones Largas con &lt;code&gt;asyncio.sleep&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Para simular una operación de I/O de larga duración (como una petición HTTP o una consulta a base de datos), podemos usar &lt;code&gt;asyncio.sleep&lt;/code&gt;. Esta función pausa la coroutine por el número de segundos indicado, cediendo el control al event loop.&lt;/p&gt;
&lt;p&gt;Veamos un ejemplo más completo con una función auxiliar &lt;code&gt;delay&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;delay&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;seconds&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Esperando &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;seconds&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; segundo(s)...&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;seconds&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;¡Espera de &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;seconds&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; segundo(s) completada!&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Esperé &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;seconds&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; segundo(s)&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="la-trampa-del-await-secuencial"&gt;La Trampa del &lt;code&gt;await&lt;/code&gt; Secuencial&lt;/h2&gt;
&lt;p&gt;Ahora veamos un error muy común al empezar con asyncio. Considera este código:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;sumar_uno&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;numero&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;) &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;numero&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;mensaje_hola_mundo&lt;/span&gt;() &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;¡Hola Mundo!&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;main&lt;/span&gt;() &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;mensaje&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;mensaje_hola_mundo&lt;/span&gt;() &lt;span style="color:#7f848e"&gt;# Pausa 1 segundo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;uno_mas_uno&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;sumar_uno&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# Ejecuta después de la pausa&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;uno_mas_uno&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;mensaje&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;run&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;main&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cuando ejecutamos este código, &lt;strong&gt;pasa 1 segundo&lt;/strong&gt; antes de que se impriman ambos resultados. Pero &lt;code&gt;sumar_uno(1)&lt;/code&gt; es instantánea — ¿por qué espera?&lt;/p&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;await&lt;/code&gt; pausa toda la coroutine contenedora.&lt;/strong&gt; No se ejecuta ningún otro código dentro de &lt;code&gt;main()&lt;/code&gt; hasta que la expresión &lt;code&gt;await&lt;/code&gt; retorne un valor. Como &lt;code&gt;mensaje_hola_mundo()&lt;/code&gt; tarda 1 segundo, &lt;code&gt;main()&lt;/code&gt; queda pausada ese segundo completo antes de siquiera llegar a &lt;code&gt;sumar_uno(1)&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;El siguiente diagrama muestra exactamente qué pasa en cada momento:&lt;/p&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 participant EL as Event Loop
 participant M as main()
 participant HW as mensaje_hola_mundo()
 participant AO as sumar_uno(1)

 EL-&gt;&gt;M: ▶ RUN main()
 Note over M: await mensaje_hola_mundo()
 M-&gt;&gt;HW: ▶ RUN mensaje_hola_mundo()
 HW-&gt;&gt;HW: await sleep(1)
 Note over M: ⏸ PAUSE main()
 Note over HW: ⏸ PAUSE mensaje_hola_mundo()
 Note over EL: ⏳ Pasa 1 segundo...
 EL-&gt;&gt;HW: ▶ RESUME mensaje_hola_mundo()
 Note over HW: return '¡Hola Mundo!'
 HW--&gt;&gt;M: ▶ RESUME main()
 Note over M: mensaje = '¡Hola Mundo!'
 Note over M: await sumar_uno(1)
 M-&gt;&gt;AO: ▶ RUN sumar_uno(1)
 Note over AO: return 1 + 1
 AO--&gt;&gt;M: ▶ RESUME main()
 Note over M: uno_mas_uno = 2
 Note over M: print() resultados
&lt;/pre&gt;

&lt;h3 id="el-problema-visualizado"&gt;El problema visualizado&lt;/h3&gt;
&lt;p&gt;El flujo de ejecución es completamente &lt;strong&gt;secuencial&lt;/strong&gt;, a pesar de usar &lt;code&gt;async/await&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="mermaid"&gt;gantt
 title Ejecución secuencial — Sin concurrencia real
 dateFormat X
 axisFormat %s

 section main()
 await mensaje_hola_mundo() :a1, 0, 10
 await sumar_uno(1) :a2, 10, 11
 print() resultados :a3, 11, 12
&lt;/pre&gt;

&lt;p&gt;Lo que &lt;em&gt;queremos&lt;/em&gt; es que &lt;code&gt;sumar_uno(1)&lt;/code&gt; se ejecute &lt;strong&gt;mientras&lt;/strong&gt; &lt;code&gt;mensaje_hola_mundo()&lt;/code&gt; espera su segundo de delay. Pero con &lt;code&gt;await&lt;/code&gt; secuencial eso no es posible — cada &lt;code&gt;await&lt;/code&gt; bloquea la coroutine hasta completarse.&lt;/p&gt;
&lt;h3 id="cómo-logramos-concurrencia-real"&gt;¿Cómo logramos concurrencia real?&lt;/h3&gt;
&lt;p&gt;Para ejecutar múltiples coroutines de forma concurrente necesitamos herramientas como &lt;code&gt;asyncio.gather&lt;/code&gt; o &lt;code&gt;asyncio.create_task&lt;/code&gt;. Un adelanto rápido:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;main&lt;/span&gt;() &lt;span style="color:#56b6c2"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;# ✅ Ambas coroutines corren concurrentemente&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;mensaje&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;uno_mas_uno&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;gather&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;mensaje_hola_mundo&lt;/span&gt;(),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;sumar_uno&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;uno_mas_uno&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;mensaje&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Con &lt;code&gt;gather&lt;/code&gt;, el event loop puede ejecutar &lt;code&gt;sumar_uno(1)&lt;/code&gt; mientras &lt;code&gt;mensaje_hola_mundo()&lt;/code&gt; está pausada esperando su &lt;code&gt;sleep&lt;/code&gt;. El tiempo total se mantiene en ~1 segundo en lugar de sumar ambos tiempos.&lt;/p&gt;
&lt;pre class="mermaid"&gt;gantt
 title Ejecución concurrente — Con asyncio.gather
 dateFormat X
 axisFormat %s

 section mensaje_hola_mundo()
 await sleep(1) :a1, 0, 10

 section sumar_uno(1)
 return 1 + 1 :a2, 0, 1

 section main()
 print() resultados :a3, 10, 11
&lt;/pre&gt;

&lt;h2 id="en-conclusión"&gt;En conclusión&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 A["async def"] --&gt;|"Define"| B["Coroutine"]
 B --&gt;|"Se ejecuta con"| C["asyncio.run()"]
 B --&gt;|"Se pausa con"| D["await"]
 D --&gt;|"Cede control al"| E["Event Loop"]
 E --&gt;|"Cuando I/O completa"| F["Reanuda la coroutine"]
 C --&gt;|"Crea y gestiona"| E

 style A fill:#8b5cf6,stroke:#5b21b6,color:#fff
 style B fill:#3b82f6,stroke:#1e40af,color:#fff
 style D fill:#f59e0b,stroke:#b45309,color:#fff
 style E fill:#10b981,stroke:#065f46,color:#fff
&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;async def&lt;/code&gt;&lt;/strong&gt; define una coroutine — una función que puede pausarse.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; pausa la coroutine actual hasta que la operación esperada termine.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;asyncio.run&lt;/code&gt;&lt;/strong&gt; crea el event loop y ejecuta la coroutine principal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;asyncio.sleep&lt;/code&gt;&lt;/strong&gt; simula operaciones de I/O de larga duración.&lt;/li&gt;
&lt;li&gt;Usar &lt;code&gt;await&lt;/code&gt; de forma secuencial &lt;strong&gt;no da concurrencia&lt;/strong&gt; — para eso necesitamos &lt;code&gt;asyncio.gather&lt;/code&gt; o &lt;code&gt;asyncio.create_task&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="referencias"&gt;Referencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/asyncio-task.html"




 target="_blank"
 


&gt;Python &lt;code&gt;asyncio&lt;/code&gt; — Documentación Oficial: Coroutines and Tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://peps.python.org/pep-0492/"




 target="_blank"
 


&gt;PEP 492 — Coroutines with async and await syntax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://realpython.com/async-io-python/"




 target="_blank"
 


&gt;Real Python — Async IO in Python: A Complete Walkthrough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>asyncio: Cómo Funcionan los Procesos, Hilos y el Event Loop</title><link>https://blog.dacadev.com/python/asyncio/procesos-hilos-event-loop/</link><pubDate>Mon, 11 May 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/asyncio/procesos-hilos-event-loop/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Entiende qué son los procesos e hilos en Python, cómo el GIL afecta la concurrencia, y cómo asyncio logra concurrencia con un solo hilo gracias al event loop.</description><media:content url="https://blog.dacadev.com/images/python/asyncio/processes-threads/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#procesos-e-hilos"&gt;Procesos e Hilos&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-un-proceso"&gt;¿Qué es un proceso?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#qué-es-un-hilo-thread"&gt;¿Qué es un hilo (thread)?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#verificándolo-en-python"&gt;Verificándolo en Python&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#el-global-interpreter-lock-gil"&gt;El Global Interpreter Lock (GIL)&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#el-gil-se-libera-alguna-vez"&gt;¿El GIL se libera alguna vez?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#asyncio-y-el-gil"&gt;&lt;code&gt;asyncio&lt;/code&gt; y el GIL&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#concurrencia-de-un-solo-hilo"&gt;Concurrencia de Un Solo Hilo&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#cómo-funciona-el-event-loop"&gt;Cómo Funciona el Event Loop&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#en-conclusión"&gt;En conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#referencias"&gt;Referencias&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;En el &lt;a href="https://blog.dacadev.com/python/asyncio/fundamentos-asyncio"



 


&gt;artículo anterior&lt;/a&gt; construimos un modelo mental sobre concurrencia, paralelismo y los tipos de multitarea. Ahora vamos a bajar un nivel: entender qué son los procesos y los hilos, por qué el GIL de Python cambia las reglas del juego, y cómo &lt;code&gt;asyncio&lt;/code&gt; logra concurrencia con un solo hilo gracias al event loop.&lt;/p&gt;
&lt;h2 id="procesos-e-hilos"&gt;Procesos e Hilos&lt;/h2&gt;
&lt;h3 id="qué-es-un-proceso"&gt;¿Qué es un proceso?&lt;/h3&gt;
&lt;p&gt;Un &lt;strong&gt;proceso&lt;/strong&gt; es una instancia de una aplicación en ejecución. Cada proceso tiene su propio espacio de memoria aislado — ningún otro proceso puede acceder a él directamente — y se ejecuta en un CPU o núcleo del sistema.&lt;/p&gt;
&lt;h3 id="qué-es-un-hilo-thread"&gt;¿Qué es un hilo (thread)?&lt;/h3&gt;
&lt;p&gt;Un &lt;strong&gt;hilo&lt;/strong&gt; es una unidad de ejecución más ligera que vive &lt;em&gt;dentro&lt;/em&gt; de un proceso. A diferencia de los procesos, los hilos no tienen su propia memoria: comparten el espacio de memoria del proceso que los creó.&lt;/p&gt;
&lt;p&gt;Todo proceso tiene al menos un hilo asociado, conocido como el &lt;strong&gt;hilo principal&lt;/strong&gt; (&lt;em&gt;main thread&lt;/em&gt;). Además, un proceso puede crear hilos adicionales, comúnmente llamados &lt;strong&gt;hilos de trabajo&lt;/strong&gt; (&lt;em&gt;worker threads&lt;/em&gt;) o &lt;strong&gt;hilos en segundo plano&lt;/strong&gt; (&lt;em&gt;background threads&lt;/em&gt;).&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TB
 subgraph P1["Proceso (PID: 1234)"]
 direction TB
 M1["Memoria del proceso"]
 MT["Hilo principal\n(main thread)"]
 W1["Worker thread 1"]
 W2["Worker thread 2"]
 M1 &lt;--&gt; MT
 M1 &lt;--&gt; W1
 M1 &lt;--&gt; W2
 end

 style P1 fill:transparent,stroke:#64748b
 style M1 fill:#3b82f6,stroke:#1e40af,color:#fff
 style MT fill:#10b981,stroke:#065f46,color:#fff
 style W1 fill:#f59e0b,stroke:#b45309,color:#fff
 style W2 fill:#f59e0b,stroke:#b45309,color:#fff
&lt;/pre&gt;





 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Todos los hilos dentro de un proceso comparten la misma memoria. Esto hace la comunicación entre hilos muy rápida, pero introduce el riesgo de &lt;strong&gt;condiciones de carrera&lt;/strong&gt; si no se maneja con cuidado.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="verificándolo-en-python"&gt;Verificándolo en Python&lt;/h3&gt;
&lt;p&gt;Puedes inspeccionar el proceso e hilo actual con los módulos &lt;code&gt;os&lt;/code&gt; y &lt;code&gt;threading&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;threading&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Proceso de Python con PID: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;os&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;getpid&lt;/span&gt;()&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;total_threads&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;threading&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;active_count&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;thread_name&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;threading&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;current_thread&lt;/span&gt;()&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Python está ejecutando &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;total_threads&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt; hilo(s)&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;El hilo actual es: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;thread_name&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# Output esperado&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Proceso de Python con PID: &lt;span style="color:#d19a66"&gt;48672&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Python está ejecutando &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; hilo&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;s&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;El hilo actual es: MainThread
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Por defecto, tu programa Python corre en un solo hilo (&lt;em&gt;MainThread&lt;/em&gt;) dentro de un solo proceso.&lt;/p&gt;
&lt;h2 id="el-global-interpreter-lock-gil"&gt;El Global Interpreter Lock (GIL)&lt;/h2&gt;
&lt;p&gt;El &lt;strong&gt;GIL&lt;/strong&gt; (&lt;em&gt;Global Interpreter Lock&lt;/em&gt;) es uno de los temas más debatidos en la comunidad Python. En términos simples: el GIL impide que un proceso de Python ejecute más de una instrucción de bytecode a la vez, incluso si tienes múltiples hilos.&lt;/p&gt;
&lt;p&gt;Esto significa que aunque crees varios hilos con &lt;code&gt;threading&lt;/code&gt;, &lt;strong&gt;solo uno ejecuta código Python en cualquier instante&lt;/strong&gt;.&lt;/p&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 participant GIL
 participant T1 as Hilo 1
 participant T2 as Hilo 2

 GIL-&gt;&gt;T1: 🔓 GIL adquirido
 activate T1
 T1-&gt;&gt;T1: Ejecuta bytecode
 T1-&gt;&gt;GIL: 🔒 Libera GIL
 deactivate T1
 GIL-&gt;&gt;T2: 🔓 GIL adquirido
 activate T2
 T2-&gt;&gt;T2: Ejecuta bytecode
 T2-&gt;&gt;GIL: 🔒 Libera GIL
 deactivate T2
 GIL-&gt;&gt;T1: 🔓 GIL adquirido
 activate T1
 T1-&gt;&gt;T1: Ejecuta bytecode
 deactivate T1
&lt;/pre&gt;

&lt;h3 id="el-gil-se-libera-alguna-vez"&gt;¿El GIL se libera alguna vez?&lt;/h3&gt;
&lt;p&gt;Sí. El GIL &lt;strong&gt;se libera durante las operaciones de I/O&lt;/strong&gt;. Cuando un hilo hace una petición de red o una lectura de disco, libera el GIL, permitiendo que otro hilo tome el control y ejecute código Python mientras tanto.&lt;/p&gt;
&lt;p&gt;Esto es lo que hace que &lt;code&gt;threading&lt;/code&gt; sea útil para trabajo I/O-bound, pero ineficaz para trabajo CPU-bound.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A["Operación\nCPU-bound"] --&gt;|"GIL retenido 🔒"| B["Solo 1 hilo\nejecuta a la vez"]
 C["Operación\nI/O-bound"] --&gt;|"GIL liberado 🔓"| D["Otros hilos pueden\nejecutar código"]

 style A fill:#ef4444,stroke:#991b1b,color:#fff
 style B fill:#ef4444,stroke:#991b1b,color:#fff
 style C fill:#10b981,stroke:#065f46,color:#fff
 style D fill:#10b981,stroke:#065f46,color:#fff
&lt;/pre&gt;

&lt;h3 id="asyncio-y-el-gil"&gt;&lt;code&gt;asyncio&lt;/code&gt; y el GIL&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;asyncio&lt;/code&gt; aprovecha exactamente este comportamiento: como las operaciones de I/O liberan el GIL, puede lograr concurrencia &lt;strong&gt;con un solo hilo&lt;/strong&gt;. En lugar de crear múltiples hilos, &lt;code&gt;asyncio&lt;/code&gt; crea objetos llamados &lt;strong&gt;coroutines&lt;/strong&gt; — que puedes pensar como hilos ultra-ligeros.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Mientras una coroutine espera por una operación de I/O, el event loop ejecuta otras coroutines que estén listas. El resultado: concurrencia sin los problemas de sincronización del multithreading.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="concurrencia-de-un-solo-hilo"&gt;Concurrencia de Un Solo Hilo&lt;/h2&gt;
&lt;p&gt;La concurrencia de un solo hilo no se basa en hacer dos cosas simultáneamente (eso sería paralelismo), sino en &lt;strong&gt;aprovechar los tiempos de espera&lt;/strong&gt; de las operaciones de I/O para ejecutar otras tareas. El mecanismo se apoya en tres pilares:&lt;/p&gt;



&lt;div class="tab" data-tab-group=""&gt;
 &lt;ul class="tab-nav" data-tab-nav&gt;
 
 &lt;li
 class="tab-nav-item active"
 data-tab="sockets-no-bloqueantes" tabindex="0"&gt;
 Sockets no bloqueantes
 &lt;/li&gt;
 
 &lt;li
 class="tab-nav-item "
 data-tab="delegaci%C3%B3n-al-so" tabindex="-1"&gt;
 Delegación al SO
 &lt;/li&gt;
 
 &lt;li
 class="tab-nav-item "
 data-tab="event-loop" tabindex="-1"&gt;
 Event Loop
 &lt;/li&gt;
 
 &lt;/ul&gt;
 &lt;div class="tab-content" data-tab-content&gt;
 
 &lt;div
 class="tab-content-panel active"
 data-tab-panel="sockets-no-bloqueantes"&gt;
 &lt;h4 id="1-sockets-no-bloqueantes"&gt;1. Sockets no bloqueantes&lt;/h4&gt;
&lt;p&gt;A diferencia de un socket estándar que detiene el programa hasta recibir una respuesta, un &lt;strong&gt;socket no bloqueante&lt;/strong&gt; permite enviar una petición y devolver el control al programa inmediatamente, sin esperar el resultado.&lt;/p&gt;

 &lt;/div&gt;
 
 &lt;div
 class="tab-content-panel "
 data-tab-panel="delegaci%C3%B3n-al-so"&gt;
 &lt;h4 id="2-delegación-al-sistema-operativo"&gt;2. Delegación al sistema operativo&lt;/h4&gt;
&lt;p&gt;Cuando el código llega a una operación de red o lectura de disco, Python le delega la espera al sistema operativo. El hilo de ejecución queda libre de inmediato.&lt;/p&gt;

 &lt;/div&gt;
 
 &lt;div
 class="tab-content-panel "
 data-tab-panel="event-loop"&gt;
 &lt;h4 id="3-el-event-loop-como-coordinador"&gt;3. El Event Loop como coordinador&lt;/h4&gt;
&lt;p&gt;Mientras el SO vigila los sockets, el hilo de Python sigue ejecutando otras tareas. Cuando el SO detecta que los datos llegaron, envía una notificación. El event loop recibe este aviso y &amp;ldquo;despierta&amp;rdquo; la tarea pausada para que procese la respuesta.&lt;/p&gt;

 &lt;/div&gt;
 
 &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;El siguiente diagrama de secuencia muestra cómo interactúan estos tres pilares:&lt;/p&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 participant MT as Main Thread
 participant EL as Event Loop
 participant OS as Sistema Operativo
 participant S1 as Socket 1
 participant S2 as Socket 2

 MT-&gt;&gt;EL: Envía tareas
 EL-&gt;&gt;EL: Ejecuta tarea 1 hasta I/O
 EL-&gt;&gt;OS: Registra Socket 1 para monitoreo
 OS-&gt;&gt;S1: Vigila socket
 EL-&gt;&gt;EL: Ejecuta tarea 2 hasta I/O
 EL-&gt;&gt;OS: Registra Socket 2 para monitoreo
 OS-&gt;&gt;S2: Vigila socket
 S1--&gt;&gt;OS: Datos listos ✅
 OS--&gt;&gt;EL: Notifica Socket 1
 EL-&gt;&gt;EL: Reanuda tarea 1
 S2--&gt;&gt;OS: Datos listos ✅
 OS--&gt;&gt;EL: Notifica Socket 2
 EL-&gt;&gt;EL: Reanuda tarea 2
&lt;/pre&gt;

&lt;h2 id="cómo-funciona-el-event-loop"&gt;Cómo Funciona el Event Loop&lt;/h2&gt;
&lt;p&gt;En su forma más básica, un event loop es simplemente un &lt;strong&gt;bucle infinito que procesa mensajes de una cola&lt;/strong&gt;, uno a la vez:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;collections&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;deque&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;messages&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;deque&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;while&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; &lt;span style="color:#e06c75"&gt;messages&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;message&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;messages&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;pop&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;process_message&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;message&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En &lt;code&gt;asyncio&lt;/code&gt;, el event loop mantiene una cola de &lt;strong&gt;tasks&lt;/strong&gt; (tareas) en lugar de mensajes simples. Cada task es un wrapper alrededor de una coroutine. Cuando una coroutine alcanza una operación de I/O, se pausa y le devuelve el control al event loop, que puede ejecutar otras tareas que no estén esperando I/O.&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 A["Event Loop inicia"] --&gt; B["¿Hay tareas en la cola?"]
 B --&gt;|Sí| C["Tomar siguiente tarea"]
 C --&gt; D{"¿La tarea tiene\nI/O pendiente?"}
 D --&gt;|No| E["Ejecutar hasta\nel próximo await"]
 E --&gt; F{"¿La tarea alcanzó\nuna operación I/O?"}
 F --&gt;|Sí| G["Pausar tarea y registrar\nsocket en el SO"]
 F --&gt;|No| H["Tarea completada ✅\nRemover de la cola"]
 G --&gt; B
 H --&gt; B
 D --&gt;|Sí, datos listos| I["Reanudar tarea"]
 I --&gt; F
 D --&gt;|Sí, esperando aún| B
 B --&gt;|No| J["Esperar notificaciones\ndel SO"]
 J --&gt; B

 style A fill:#3b82f6,stroke:#1e40af,color:#fff
 style H fill:#10b981,stroke:#065f46,color:#fff
&lt;/pre&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Este ciclo se repite indefinidamente hasta que todas las tareas se completan o el programa se cierra explícitamente. Si una coroutine ejecuta trabajo CPU-bound sin ceder control con &lt;code&gt;await&lt;/code&gt;, &lt;strong&gt;bloqueará todo el event loop&lt;/strong&gt; y ninguna otra tarea podrá avanzar.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="en-conclusión"&gt;En conclusión&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Un &lt;strong&gt;proceso&lt;/strong&gt; tiene memoria aislada; un &lt;strong&gt;hilo&lt;/strong&gt; comparte memoria dentro de su proceso.&lt;/li&gt;
&lt;li&gt;El &lt;strong&gt;GIL&lt;/strong&gt; impide paralelismo real con hilos en Python, pero se libera durante operaciones de I/O.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;asyncio&lt;/code&gt; aprovecha esta liberación del GIL para lograr &lt;strong&gt;concurrencia en un solo hilo&lt;/strong&gt; mediante coroutines.&lt;/li&gt;
&lt;li&gt;El &lt;strong&gt;event loop&lt;/strong&gt; coordina las tareas: ejecuta coroutines hasta que alcanzan un &lt;code&gt;await&lt;/code&gt;, las pausa, y reanuda otras que ya tengan datos listos.&lt;/li&gt;
&lt;li&gt;Los &lt;strong&gt;sockets no bloqueantes&lt;/strong&gt; y la &lt;strong&gt;delegación al SO&lt;/strong&gt; son los mecanismos que permiten esta concurrencia sin crear múltiples hilos.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="referencias"&gt;Referencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/asyncio.html"




 target="_blank"
 


&gt;Python &lt;code&gt;asyncio&lt;/code&gt; — Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/threading.html"




 target="_blank"
 


&gt;Python &lt;code&gt;threading&lt;/code&gt; — Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/multiprocessing.html"




 target="_blank"
 


&gt;Python &lt;code&gt;multiprocessing&lt;/code&gt; — Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://realpython.com/python-gil/"




 target="_blank"
 


&gt;Real Python — What Is the Python Global Interpreter Lock (GIL)?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://peps.python.org/pep-0703/"




 target="_blank"
 


&gt;PEP 703 — Making the Global Interpreter Lock Optional&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>asyncio: Los Fundamentos de la Programación Asíncrona en Python</title><link>https://blog.dacadev.com/python/asyncio/fundamentos-asyncio/</link><pubDate>Sun, 10 May 2026 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/asyncio/fundamentos-asyncio/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Aprende los fundamentos de asyncio en Python: diferencia entre concurrencia y paralelismo, operaciones CPU-bound vs I/O-bound, y cómo funciona la multitarea cooperativa.</description><media:content url="https://blog.dacadev.com/images/python/asyncio/fundamentals/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-la-programación-asíncrona"&gt;¿Qué es la programación asíncrona?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#cpu-bound-vs-io-bound"&gt;CPU-bound vs. I/O-bound&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#operaciones-limitadas-por-es-io-bound"&gt;Operaciones limitadas por E/S (I/O-bound)&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#operaciones-limitadas-por-cpu-cpu-bound"&gt;Operaciones limitadas por CPU (CPU-bound)&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#ejemplo-práctico"&gt;Ejemplo práctico&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#concurrencia-vs-paralelismo"&gt;Concurrencia vs. Paralelismo&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#concurrencia-alternar-entre-tareas"&gt;Concurrencia: alternar entre tareas&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#paralelismo-ejecución-simultánea-real"&gt;Paralelismo: ejecución simultánea real&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipos-de-multitarea"&gt;Tipos de Multitarea&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#multitarea-preventiva-preemptive"&gt;Multitarea preventiva (Preemptive)&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#multitarea-cooperativa-cooperative"&gt;Multitarea cooperativa (Cooperative)&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#comparación-rápida"&gt;Comparación rápida&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#dónde-encaja-asyncio"&gt;¿Dónde encaja &lt;code&gt;asyncio&lt;/code&gt;?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#en-conclusión"&gt;En conclusión&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#referencias"&gt;Referencias&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;

&lt;p&gt;Si alguna vez construiste un scraper que recorre decenas de páginas, un microservicio que atiende cientos de peticiones o un bot que consume múltiples APIs, seguro sentiste la frustración de esperar. Una petición termina, la siguiente arranca, y tu programa queda ahí sin hacer nada útil.&lt;/p&gt;
&lt;p&gt;La librería &lt;code&gt;asyncio&lt;/code&gt; de Python fue diseñada para resolver exactamente este problema. En este artículo vamos a construir un modelo mental sólido sobre los conceptos clave: concurrencia, paralelismo, multitarea y la diferencia entre operaciones limitadas por CPU y por E/S.&lt;/p&gt;
&lt;h2 id="qué-es-la-programación-asíncrona"&gt;¿Qué es la programación asíncrona?&lt;/h2&gt;
&lt;p&gt;La &lt;strong&gt;programación asíncrona&lt;/strong&gt; es un modelo donde las tareas de larga duración se ejecutan en segundo plano, separadas del flujo principal de tu aplicación. En lugar de bloquear todo mientras esperas una respuesta de red o una lectura de archivo, el sistema queda libre para hacer otro trabajo. Cuando la tarea termina, tu código recibe una notificación y puede procesar el resultado.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;asyncio&lt;/code&gt; — abreviación de &lt;strong&gt;asynchronous I/O&lt;/strong&gt; — es la librería estándar de Python que implementa este modelo. Fue introducida en &lt;a href="https://docs.python.org/3/library/asyncio.html"




 target="_blank"
 


&gt;Python 3.4&lt;/a&gt; y hoy es la base de frameworks modernos como &lt;a href="https://fastapi.tiangolo.com/"




 target="_blank"
 


&gt;FastAPI&lt;/a&gt;, &lt;a href="https://docs.aiohttp.org/"




 target="_blank"
 


&gt;aiohttp&lt;/a&gt; y &lt;a href="https://www.starlette.io/"




 target="_blank"
 


&gt;Starlette&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="cpu-bound-vs-io-bound"&gt;CPU-bound vs. I/O-bound&lt;/h2&gt;
&lt;p&gt;Antes de avanzar, necesitas entender una distinción fundamental: &lt;strong&gt;¿en qué está gastando tiempo tu código?&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="operaciones-limitadas-por-es-io-bound"&gt;Operaciones limitadas por E/S (I/O-bound)&lt;/h3&gt;
&lt;p&gt;Tu programa pasa la mayor parte del tiempo &lt;strong&gt;esperando un sistema externo&lt;/strong&gt;: la red, el disco, una base de datos. La CPU está prácticamente ociosa. Ejemplos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hacer peticiones HTTP.&lt;/li&gt;
&lt;li&gt;Leer o escribir archivos en disco.&lt;/li&gt;
&lt;li&gt;Consultar una base de datos.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="operaciones-limitadas-por-cpu-cpu-bound"&gt;Operaciones limitadas por CPU (CPU-bound)&lt;/h3&gt;
&lt;p&gt;El &lt;strong&gt;procesador&lt;/strong&gt; es el cuello de botella. La CPU está activamente calculando, sin esperas externas. Ejemplos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Calcular dígitos de pi.&lt;/li&gt;
&lt;li&gt;Aplicar lógica de negocio sobre estructuras de datos grandes.&lt;/li&gt;
&lt;li&gt;Procesamiento de imágenes o entrenamiento de modelos.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ejemplo-práctico"&gt;Ejemplo práctico&lt;/h3&gt;
&lt;p&gt;Considera este fragmento de código:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;requests&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;response&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;requests&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;get&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;https://www.example.com&amp;#39;&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 1 - I/O-bound&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;items&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;response&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;headers&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;items&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;headers&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#98c379"&gt;f&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;key&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;: &lt;/span&gt;&lt;span style="color:#98c379"&gt;{&lt;/span&gt;&lt;span style="color:#e06c75"&gt;header&lt;/span&gt;&lt;span style="color:#98c379"&gt;}&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt; &lt;span style="color:#c678dd"&gt;for&lt;/span&gt; &lt;span style="color:#e06c75"&gt;key&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;header&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;in&lt;/span&gt; &lt;span style="color:#e06c75"&gt;items&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;# 2 - CPU-bound&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;formatted_headers&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#98c379"&gt;\n&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;join&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;headers&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 3 - CPU-bound&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;with&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;open&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;headers.txt&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;) &lt;span style="color:#c678dd"&gt;as&lt;/span&gt; &lt;span style="color:#e06c75"&gt;file&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;file&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;write&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;formatted_headers&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 4 - I/O-bound&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El siguiente diagrama muestra el flujo de ejecución y clasifica cada paso:&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart LR
 A["1. requests.get()"] --&gt;|respuesta| B["2. List comprehension"]
 B --&gt; C["3. join() headers"]
 C --&gt; D["4. file.write()"]

 style A fill:#3b82f6,stroke:#1e40af,color:#fff
 style B fill:#f59e0b,stroke:#b45309,color:#fff
 style C fill:#f59e0b,stroke:#b45309,color:#fff
 style D fill:#3b82f6,stroke:#1e40af,color:#fff
&lt;/pre&gt;

&lt;blockquote&gt;
&lt;p&gt;🔵 &lt;strong&gt;Azul = I/O-bound&lt;/strong&gt; (esperando red o disco) · 🟡 &lt;strong&gt;Amarillo = CPU-bound&lt;/strong&gt; (procesando en memoria)&lt;/p&gt;
&lt;/blockquote&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;code&gt;asyncio&lt;/code&gt; brilla con cargas &lt;strong&gt;I/O-bound&lt;/strong&gt;. Si tu cuello de botella es la CPU, necesitarás &lt;code&gt;multiprocessing&lt;/code&gt; o &lt;a href="https://docs.python.org/3/library/concurrent.futures.html"




 target="_blank"
 


&gt;concurrent.futures&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="concurrencia-vs-paralelismo"&gt;Concurrencia vs. Paralelismo&lt;/h2&gt;
&lt;p&gt;Estos dos términos se confunden constantemente, pero describen cosas distintas.&lt;/p&gt;
&lt;h3 id="concurrencia-alternar-entre-tareas"&gt;Concurrencia: alternar entre tareas&lt;/h3&gt;
&lt;p&gt;Concurrencia significa &lt;strong&gt;gestionar múltiples tareas en períodos de tiempo superpuestos&lt;/strong&gt;, sin necesidad de ejecutarlas en el mismo instante. Piensa en un chef preparando dos platos: pica verduras para el plato A, lo mete al horno y empieza a trabajar en el plato B mientras el A se cocina. Solo hace una cosa a la vez, pero ambos platos avanzan.&lt;/p&gt;
&lt;p&gt;En un sistema concurrente, una sola CPU alterna entre tareas. Mientras la tarea #1 espera por E/S, la CPU toma la tarea #2.&lt;/p&gt;
&lt;pre class="mermaid"&gt;gantt
 title Concurrencia — Una sola CPU alternando entre tareas
 dateFormat X
 axisFormat %s

 section CPU
 App #1 :a1, 0, 2
 App #2 :a2, 2, 4
 App #1 :a3, 4, 6
 App #2 :a4, 6, 8
 App #1 :a5, 8, 10
&lt;/pre&gt;

&lt;h3 id="paralelismo-ejecución-simultánea-real"&gt;Paralelismo: ejecución simultánea real&lt;/h3&gt;
&lt;p&gt;Paralelismo significa &lt;strong&gt;ejecutar múltiples tareas al mismo tiempo&lt;/strong&gt;, lo cual requiere múltiples CPUs o núcleos.&lt;/p&gt;
&lt;pre class="mermaid"&gt;gantt
 title Paralelismo — Múltiples CPUs ejecutando simultáneamente
 dateFormat X
 axisFormat %s

 section CPU 1
 App #1 :a1, 0, 10

 section CPU 2
 App #2 :b1, 0, 10
&lt;/pre&gt;

&lt;p&gt;En palabras de Rob Pike (co-creador de Go): &lt;em&gt;&amp;ldquo;La concurrencia se trata de lidiar con muchas cosas a la vez. El paralelismo se trata de hacer muchas cosas a la vez.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;La concurrencia es un &lt;strong&gt;patrón de diseño&lt;/strong&gt;; el paralelismo es un &lt;strong&gt;modelo de ejecución&lt;/strong&gt;. &lt;code&gt;asyncio&lt;/code&gt; logra concurrencia en un solo hilo, sin paralelismo.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="tipos-de-multitarea"&gt;Tipos de Multitarea&lt;/h2&gt;
&lt;p&gt;Existen dos enfoques principales para la multitarea, y entender la diferencia es clave para comprender dónde encaja &lt;code&gt;asyncio&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="multitarea-preventiva-preemptive"&gt;Multitarea preventiva (Preemptive)&lt;/h3&gt;
&lt;p&gt;El &lt;strong&gt;sistema operativo&lt;/strong&gt; decide cuándo cambiar entre tareas mediante un mecanismo llamado &lt;strong&gt;time slicing&lt;/strong&gt;: divide el tiempo de CPU en intervalos pequeños y rota entre las tareas activas. Cuando el SO fuerza un cambio, se dice que está haciendo &lt;em&gt;preemption&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;En Python, este es el modelo que usan los módulos &lt;code&gt;threading&lt;/code&gt; (hilos) y &lt;code&gt;multiprocessing&lt;/code&gt; (procesos). La ventaja es que no tienes que pensar en cuándo ceder el control. La desventaja: los cambios pueden ocurrir en cualquier momento, lo que introduce &lt;strong&gt;condiciones de carrera&lt;/strong&gt; y la necesidad de &lt;strong&gt;locks&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="multitarea-cooperativa-cooperative"&gt;Multitarea cooperativa (Cooperative)&lt;/h3&gt;
&lt;p&gt;Las &lt;strong&gt;propias tareas&lt;/strong&gt; deciden cuándo ceder el control. Cada tarea señala explícitamente: &lt;em&gt;&amp;ldquo;Me pauso aquí, ejecuta otras tareas.&amp;rdquo;&lt;/em&gt; No hay intervención del SO.&lt;/p&gt;
&lt;p&gt;Este es exactamente el modelo de &lt;code&gt;asyncio&lt;/code&gt;. En Python, la palabra clave &lt;code&gt;await&lt;/code&gt; es esa señal explícita:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;obtener_datos&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Obteniendo datos...&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 👈 &amp;#34;Me pauso aquí, ejecuta otras tareas&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Datos obtenidos!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;procesar_datos&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Procesando datos...&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;sleep&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;) &lt;span style="color:#7f848e"&gt;# 👈 Misma señal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Datos procesados!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;async&lt;/span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;main&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;await&lt;/span&gt; &lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;gather&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;obtener_datos&lt;/span&gt;(), &lt;span style="color:#e06c75"&gt;procesar_datos&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;asyncio&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;run&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;main&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La ventaja es la &lt;strong&gt;predictibilidad&lt;/strong&gt;: tú controlas exactamente dónde ocurren los cambios. El riesgo: si una tarea olvida hacer &lt;code&gt;await&lt;/code&gt; o ejecuta una operación CPU-bound larga sin ceder control, bloquea todo el event loop.&lt;/p&gt;
&lt;p&gt;El siguiente diagrama de secuencia ilustra cómo el event loop coordina las tareas cooperativamente:&lt;/p&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 participant EL as Event Loop
 participant T1 as obtener_datos()
 participant T2 as procesar_datos()

 EL-&gt;&gt;T1: Ejecutar
 T1-&gt;&gt;EL: await sleep(2) — cede control
 EL-&gt;&gt;T2: Ejecutar
 T2-&gt;&gt;EL: await sleep(1) — cede control
 EL-&gt;&gt;T2: sleep completado — reanudar
 T2-&gt;&gt;EL: Finalizada ✅
 EL-&gt;&gt;T1: sleep completado — reanudar
 T1-&gt;&gt;EL: Finalizada ✅
&lt;/pre&gt;

&lt;h3 id="comparación-rápida"&gt;Comparación rápida&lt;/h3&gt;



&lt;div class="tab" data-tab-group=""&gt;
 &lt;ul class="tab-nav" data-tab-nav&gt;
 
 &lt;li
 class="tab-nav-item active"
 data-tab="preventiva" tabindex="0"&gt;
 Preventiva
 &lt;/li&gt;
 
 &lt;li
 class="tab-nav-item "
 data-tab="cooperativa" tabindex="-1"&gt;
 Cooperativa
 &lt;/li&gt;
 
 &lt;/ul&gt;
 &lt;div class="tab-content" data-tab-content&gt;
 
 &lt;div
 class="tab-content-panel active"
 data-tab-panel="preventiva"&gt;
 &lt;h4 id="multitarea-preventiva"&gt;Multitarea Preventiva&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;¿Quién cambia?&lt;/strong&gt; El Sistema Operativo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mecanismo:&lt;/strong&gt; Time slicing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Herramientas en Python:&lt;/strong&gt; &lt;code&gt;threading&lt;/code&gt;, &lt;code&gt;multiprocessing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Riesgo principal:&lt;/strong&gt; Condiciones de carrera&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ideal para:&lt;/strong&gt; Cargas CPU-bound o mixtas&lt;/li&gt;
&lt;/ul&gt;

 &lt;/div&gt;
 
 &lt;div
 class="tab-content-panel "
 data-tab-panel="cooperativa"&gt;
 &lt;h4 id="multitarea-cooperativa"&gt;Multitarea Cooperativa&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;¿Quién cambia?&lt;/strong&gt; La propia tarea&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mecanismo:&lt;/strong&gt; &lt;code&gt;await&lt;/code&gt; / yield&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Herramientas en Python:&lt;/strong&gt; &lt;code&gt;asyncio&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Riesgo principal:&lt;/strong&gt; Bloquear el event loop&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ideal para:&lt;/strong&gt; Cargas I/O-bound&lt;/li&gt;
&lt;/ul&gt;

 &lt;/div&gt;
 
 &lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="dónde-encaja-asyncio"&gt;¿Dónde encaja &lt;code&gt;asyncio&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;Con todos estos conceptos claros, el siguiente diagrama te ayuda a decidir qué herramienta usar según tu caso:&lt;/p&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 A["¿Qué tipo de operación\nnecesitas optimizar?"] --&gt; B{"¿Es I/O-bound?"}
 B --&gt;|Sí| C{"¿Necesitas manejar\nmuchas conexiones?"}
 C --&gt;|Sí| D["✅ asyncio"]
 C --&gt;|No| E["threading o\nasyncio"]
 B --&gt;|No| F{"¿Es CPU-bound?"}
 F --&gt;|Sí| G{"¿Necesitas compartir\nmemoria entre tareas?"}
 G --&gt;|Sí| H["threading\n+ locks"]
 G --&gt;|No| I["multiprocessing"]
 F --&gt;|Mixto| J["asyncio +\nrun_in_executor()"]

 style D fill:#10b981,stroke:#065f46,color:#fff
 style E fill:#10b981,stroke:#065f46,color:#fff
 style H fill:#f59e0b,stroke:#b45309,color:#fff
 style I fill:#3b82f6,stroke:#1e40af,color:#fff
 style J fill:#8b5cf6,stroke:#5b21b6,color:#fff
&lt;/pre&gt;

&lt;h2 id="en-conclusión"&gt;En conclusión&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;asyncio&lt;/code&gt; ofrece &lt;strong&gt;concurrencia&lt;/strong&gt;, no paralelismo — todo corre en un solo hilo.&lt;/li&gt;
&lt;li&gt;Usa &lt;strong&gt;multitarea cooperativa&lt;/strong&gt; — tu código cede control explícitamente con &lt;code&gt;await&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Destaca en cargas &lt;strong&gt;I/O-bound&lt;/strong&gt; — peticiones de red, operaciones de archivo, consultas a bases de datos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No es la solución&lt;/strong&gt; para trabajo CPU-bound — para eso, combínalo con &lt;code&gt;multiprocessing&lt;/code&gt; o usa &lt;a href="https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor"




 target="_blank"
 


&gt;loop.run_in_executor()&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="referencias"&gt;Referencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/asyncio.html"




 target="_blank"
 


&gt;Python &lt;code&gt;asyncio&lt;/code&gt; — Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.python.org/3/library/concurrent.futures.html"




 target="_blank"
 


&gt;Python &lt;code&gt;concurrent.futures&lt;/code&gt; — Documentación Oficial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://realpython.com/async-io-python/"




 target="_blank"
 


&gt;Real Python — Async IO in Python: A Complete Walkthrough&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://peps.python.org/pep-3156/"




 target="_blank"
 


&gt;PEP 3156 — Asynchronous IO Support Rebooted&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Tipado básico en Python</title><link>https://blog.dacadev.com/python/tipado/02-tipado-basico/</link><pubDate>Sat, 10 Aug 2024 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/tipado/02-tipado-basico/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Aprende a aplicar tipos en Python de manera efectiva. Descubre cómo agregar tipado en variables, colecciones, y funciones en Python. Incluye ejemplos prácticos y recomendaciones según la versión de Python.</description><media:content url="https://blog.dacadev.com/images/python/typing/bases/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#tipos-buitl-in-in-python"&gt;Tipos Buitl-in in Python&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#tipado-en-colecciones"&gt;Tipado en colecciones&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#combinación-de-tipos-en-python"&gt;Combinación de Tipos en Python&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#definir-más-de-un-tipo"&gt;Definir Más de un Tipo&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#valores-opcionales-o-none"&gt;Valores Opcionales o &lt;code&gt;None&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#definir-valores-fijos"&gt;Definir Valores Fijos&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#definir-tipos-personalizados"&gt;Definir Tipos Personalizados&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#datos-io-en-python"&gt;Datos IO en Python&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;p&gt;Este artículo es parte de una serie que explica el tipado en Python. A continuación, puedes ver la recopilación de todos los posts de la serie.
&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.dacadev.com/python/tipado/serie-de-tipado" class="btn btn-outline-primary " rel="" &gt;Ver serie&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Agregar tipos en Python es muy sencillo y tiene una sintaxis similar a otros lenguajes como &lt;em&gt;Typescript&lt;/em&gt;. &lt;strong&gt;No es obligatorio&lt;/strong&gt; aplicar tipado en cada pieza de código, lo que permite agregarlo de manera gradual. Además, agregar o no tipos no afectará el comportamiento del código.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;La posibilidad de agregar tipado en Python está disponible desde la versión &lt;strong&gt;3.5&lt;/strong&gt;. Desde entonces, se han añadido nuevas características y mejoras.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="tipos-buitl-in-in-python"&gt;Tipos Buitl-in in Python&lt;/h2&gt;
&lt;p&gt;Los tipos &lt;em&gt;built-in&lt;/em&gt; son aquellos que vienen por defecto en Python, como &lt;code&gt;str&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;bytes&lt;/code&gt;, &lt;code&gt;None&lt;/code&gt;, &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, &lt;code&gt;tuple&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, entre otros.&lt;/p&gt;
&lt;p&gt;Para agregar tipado a una variable, simplemente añade &lt;code&gt;:&lt;/code&gt; después del nombre de la variable y luego especifica el tipo de dato. La sintaxis es:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;variable&amp;gt;: &amp;lt;type&amp;gt; = &amp;lt;value&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ejemplo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;n&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;f&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;float&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;10.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;c&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;complex&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;&lt;span style="color:#e06c75"&gt;j&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;s&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;bytes&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;b&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;bytes&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;t&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;hello world&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;v&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En el anterior ejemplo estamos definiendo que cada una de las variables solo van a manejar un tipo de datos a lo largo de vida en el programa.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Recuerda que el agregar el tipo de dato no afecta el comportamiento del código, es solo una ayuda para el programador, analizadores de código estáticos e IDEs.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="tipado-en-colecciones"&gt;Tipado en colecciones&lt;/h2&gt;
&lt;p&gt;Para colecciones como &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, &lt;code&gt;tuple&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, la sintaxis es similar a la de las variables simples. salvo que podemos definir o nor el tipo de variable que cada variable va a contener. es decir que tenemos dos tipos de sintaxis que podemos utilizar.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;variable&amp;gt;: &amp;lt;collection&amp;gt; = &amp;lt;value&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;variable&amp;gt;: &amp;lt;collection&amp;gt;[&amp;lt;type&amp;gt;...] = &amp;lt;value&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En la primera opción estamos definiendo que la variable va a ser de tipo &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, &lt;code&gt;tuple&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt; y en la segunda opción estamos definiendo que la variable va a ser de tipo &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, &lt;code&gt;tuple&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt; y que va a contener un tipo de dato especifico. Veamos como se aplica esto en algunos ejemplos, para ello es importante tener en cuenta la versión de Python que estás utilizando.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python 3.5 a 3.8:&lt;/strong&gt; Es necesario importar los tipos de la librería &lt;code&gt;typing&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;List&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Set&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Tuple&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Dict&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;l&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;List&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;s&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Set&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {&lt;span style="color:#98c379"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;world&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;t&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Tuple&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;10&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;Python&amp;#34;&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;d&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Dict&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {&lt;span style="color:#98c379"&gt;&amp;#34;active&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;True&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;False&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Python 3.9 y posteriores:&lt;/strong&gt; Puedes utilizar la sintaxis estándar sin importar &lt;code&gt;typing&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;l&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;list&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;4&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;s&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;set&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {&lt;span style="color:#98c379"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;world&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;t&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;tuple&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; (&lt;span style="color:#d19a66"&gt;10&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;Python&amp;#34;&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;d&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;dict&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {&lt;span style="color:#98c379"&gt;&amp;#34;active&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;True&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;False&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En los ejemplos anteriores podemos observar que estamos definiendo un tipo de colección diferente por cada varibale y cabe destacar que en el caso de las colecciones podemos definir el tipo de dato que va a contener cada una de las variables, debes tener en cuenta que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;para &lt;code&gt;list&lt;/code&gt; y &lt;code&gt;set&lt;/code&gt; se utiliza el tipo de dato que va a contener entre corchetes &lt;code&gt;[]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;para &lt;code&gt;tuple&lt;/code&gt; se define el tipo de dato y la posición dentro de la tupla entre corchetes &lt;code&gt;[]&lt;/code&gt;, es decir que en el ejemplo se espera que sea una tupla de tres elementos que estaran en el siguiente orden &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;str&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;para &lt;code&gt;dict&lt;/code&gt; se define el tipo de dato que va a contener la llave y el valor entre corchetes &lt;code&gt;[]&lt;/code&gt;, es decir que en el ejemplo se espera que sea un diccionario con llaves de tipo &lt;code&gt;str&lt;/code&gt; y valores de tipo &lt;code&gt;bool&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="combinación-de-tipos-en-python"&gt;Combinación de Tipos en Python&lt;/h2&gt;
&lt;p&gt;En algunos casos, es necesario que las variables puedan contener más de un tipo de dato o incluso que puedan ser opcionales. Para ello se han definido diversas estrategias para alcanzar esta funcionalidad&lt;/p&gt;
&lt;h3 id="definir-más-de-un-tipo"&gt;Definir Más de un Tipo&lt;/h3&gt;
&lt;p&gt;Utiliza el carácter &lt;code&gt;|&lt;/code&gt; para definir más de un tipo de dato en una variable, este carácter actúa como un &lt;code&gt;OR&lt;/code&gt; lógico:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;one&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Para versiones anteriores a Python 3.9, importa &lt;code&gt;Union&lt;/code&gt; de &lt;code&gt;typing&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Union&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Union&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Union&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;one&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="valores-opcionales-o-none"&gt;Valores Opcionales o &lt;code&gt;None&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Para definir que un valor es opcional, añade &lt;code&gt;None&lt;/code&gt; como parte de los tipos posibles:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;b&lt;/span&gt;: &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Para versiones anteriores a Python 3.9, utiliza &lt;code&gt;Optional&lt;/code&gt; o &lt;code&gt;Union&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# Opción 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Optional&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Optional&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# Opción 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Union&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Union&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;] &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="definir-valores-fijos"&gt;Definir Valores Fijos&lt;/h3&gt;
&lt;p&gt;Si deseas restringir los valores que puede tomar una variable, usa &lt;code&gt;Literal&lt;/code&gt; de &lt;code&gt;typing&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Literal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;cards&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;Literal&lt;/span&gt;[&lt;span style="color:#98c379"&gt;&amp;#34;clubs&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;diamonds&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;hearts&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;spades&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;cards&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;clubs&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="definir-tipos-personalizados"&gt;Definir Tipos Personalizados&lt;/h2&gt;
&lt;p&gt;EN Python asi como con las variables es posible definir tipos personalizados, para simplificar la lectura del código o incluso para darle un mejor entendimiento al código. en la siguiente pieza de código podemos ver esta funcionalidad.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Literal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;UserType&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Literal&lt;/span&gt;[&lt;span style="color:#98c379"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ID&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;int&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;PersonalData&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;dict&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;float&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;User&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;tuple&lt;/span&gt;[&lt;span style="color:#e06c75"&gt;ID&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;PersonalData&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;UserType&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;UserUgly&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;tuple&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;dict&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;float&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;|&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;], &lt;span style="color:#e06c75"&gt;Literal&lt;/span&gt;[&lt;span style="color:#98c379"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Como podemos observa en el ejemplo anterior estamos separando nuestra definición de tipos en otros tipos para facilitar la lectura de nuestro código, en el caso de &lt;code&gt;User&lt;/code&gt; y &lt;code&gt;UserUgly&lt;/code&gt; estamos definiendo un tipo de dato que va a ser una tupla que va a contener un &lt;code&gt;ID&lt;/code&gt;, &lt;code&gt;PersonalData&lt;/code&gt; y &lt;code&gt;UserType&lt;/code&gt; y en el caso de &lt;code&gt;UserUgly&lt;/code&gt; estamos definiendo el mismo tipo de dato pero de una manera menos legible.&lt;/p&gt;
&lt;p&gt;si escribieramos el mismo código para versiones anteriores a Python 3.9, el código se vería de la siguiente manera:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Literal&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Union&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Optional&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;UserType&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Literal&lt;/span&gt;[&lt;span style="color:#98c379"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;ID&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Union&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;PersonalData&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;dict&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;Optional&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;bool&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;float&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;User&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;tuple&lt;/span&gt;[&lt;span style="color:#e06c75"&gt;ID&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;PersonalData&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;UserType&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="datos-io-en-python"&gt;Datos IO en Python&lt;/h2&gt;
&lt;p&gt;Cuando trabajes con datos de entrada/salida, como la lectura de archivos, usa el tipo &lt;code&gt;IO&lt;/code&gt; de &lt;code&gt;typing&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;typing&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;IO&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;text_file&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;IO&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;# text, json, xml, html...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;bin_file&lt;/span&gt;: &lt;span style="color:#e06c75"&gt;IO&lt;/span&gt;[&lt;span style="color:#e5c07b"&gt;bytes&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;# jpeg, png, pdf, mp3...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El tipo &lt;code&gt;IO&lt;/code&gt; es un tipo genérico que se utiliza para representar objetos que son streams de entrada o salida, como archivos y sockets, y solo admite tipos de datos &lt;code&gt;str&lt;/code&gt; y &lt;code&gt;bytes&lt;/code&gt;.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;p&gt;En este artículo, hemos cubierto las nociones básicas sobre cómo agregar tipos a tus variables en Python. En el próximo artículo, exploraremos cómo agregar tipos a funciones y métodos.&lt;/p&gt;
&lt;!-- &lt;br /&gt;&lt;br /&gt;






 
 
 
 
 
 
 
 
 
 


&lt;a href="https://blog.dacadev.com/python/tipado/tipado-de-funciones-y-metodos" class="btn btn-outline-primary " rel="" &gt;Siguiente artículo&lt;/a&gt;
 --&gt;&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>Tipado en Python: Introducción</title><link>https://blog.dacadev.com/python/tipado/01-introduccion/</link><pubDate>Fri, 09 Aug 2024 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/tipado/01-introduccion/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Descubre por qué el tipado en Python es clave para proyectos profesionales. Aprende sobre errores de lógica, validación de tipos y cómo mejorar la calidad de tu código.</description><media:content url="https://blog.dacadev.com/images/python/typing/introduction/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#por-qué-es-importante-el-tipado"&gt;¿Por qué es importante el tipado?&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#tipos-de-errores"&gt;Tipos de errores&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;p&gt;Este artículo hace parte de una serie que explicará el tipado en Python, a continuación puedes ver la recopilación de todos los posts de la serie.
&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.dacadev.com/python/tipado/serie-de-tipado" class="btn btn-outline-primary " rel="" &gt;Ver serie&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="por-qué-es-importante-el-tipado"&gt;¿Por qué es importante el tipado?&lt;/h2&gt;
&lt;p&gt;Antes de ahondar en el uso de tipos en python, debemos hacer un pequeño énfasis de porque nace la necesidad de implementar &lt;em&gt;“tipado”&lt;/em&gt; y análisis estático de código en Python&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Escribo tipado entre comillas porque realmente no implementamos tipado en python, sino que simulamos tener tipos en Python, esto lo veremos vas adelante, pero es importante tenerlo en cuenta.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Python, al ser un lenguaje &lt;strong&gt;interpretado&lt;/strong&gt;, significa que el código es leído y ejecutado solamente cuando el interprete pasa por la línea de código, por lo que el error, si existe, solo aparecerá cuando ejecutamos dicha línea de código. Por el contrario en un lenguaje compilado como Go o Java, el código debe primero construido (compilado) y después usado, pero es en el proceso de compilación en donde se realizan validaciones de tipos dentro del código y estas validaciones permiten capturar errores tempranos.&lt;/p&gt;
&lt;h3 id="tipos-de-errores"&gt;Tipos de errores&lt;/h3&gt;
&lt;p&gt;En este punto vale la pena agrupar los errores en dos grupos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Errores de excepción: Son errores que se generan cuando un programa falla al ejecutar una acción determinada, como por ejemplo abrir un archivo que no existe.&lt;/li&gt;
&lt;li&gt;Errores de lógica: Son errores que no generan excepción sino que generan un resultado errado al esperado.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice warning"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Warning&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Los errores de lógica son los mas peligrosos ya que al no levantar una excepción normalmente permiten que el flujo de trabajo continue con los errores.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;hr&gt;
&lt;p&gt;En ese orden de ideas nos centraremos en los errores de &lt;strong&gt;lógica&lt;/strong&gt; ya que son los errores que podemos &lt;em&gt;&amp;ldquo;capturar&amp;rdquo;&lt;/em&gt; gracias a los tipos, por ejemplo con ayuda de tipos podemos capturar errores tempranos como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;validar el uso de los tipos de datos dentro de nuestro código, por ejemplo si estamos usando un string en un lugar donde deberíamos de usar un entero&lt;/li&gt;
&lt;li&gt;validar que los métodos que estamos llamando existan en el objeto que estamos usando&lt;/li&gt;
&lt;li&gt;validar que los atributos que estamos usando en un objeto existan&lt;/li&gt;
&lt;li&gt;validar que los argumentos que estamos pasando a una función sean los correctos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Veamos la forma tradicional de validar y capturar errores de tipos en Python. Para ello debemos de implementar una serie sentencias en nuestro código para asegurarnos que estamos usando los tipos correctos. esto puede afectar la legibilidad del código y la productividad, e incluso el rendimiento de nuestros programas en algunos casos.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;clean_text&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;assert&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;isinstance&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;a&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;str&lt;/span&gt;), &lt;span style="color:#98c379"&gt;&amp;#34;Input must be a string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#7f848e"&gt;# process a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;calculate_sum&lt;/span&gt;(&lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;&lt;span style="color:#e06c75"&gt;nums&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;sum&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#d19a66"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;for&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;in&lt;/span&gt; &lt;span style="color:#e06c75"&gt;nums&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;if&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;not&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;isinstance&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;num&lt;/span&gt;, (&lt;span style="color:#e5c07b"&gt;int&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;float&lt;/span&gt;)):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;raise&lt;/span&gt; &lt;span style="color:#e06c75"&gt;ValueError&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Input must be a number&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e5c07b"&gt;sum&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;num&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;sum&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En el caso de &lt;code&gt;clean_text&lt;/code&gt; estamos validando que el argumento &lt;code&gt;a&lt;/code&gt; sea un &lt;code&gt;string&lt;/code&gt;, en caso de que no sea un &lt;code&gt;string&lt;/code&gt;, levantamos una excepción. En el caso de &lt;code&gt;calculate_sum&lt;/code&gt; estamos validando que los argumentos que estamos pasando sean &lt;code&gt;int&lt;/code&gt; o &lt;code&gt;float&lt;/code&gt;, en caso de que no sea alguno de estos, levantamos una excepción.&lt;/p&gt;




 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En el caso &lt;code&gt;clean_text&lt;/code&gt; estamos usando &lt;code&gt;assert&lt;/code&gt; para validar el tipo de dato, sin embargo &lt;code&gt;assert&lt;/code&gt; no es recomendado para validar tipos de datos, ya que se puede desactivar en tiempo de ejecución, por lo que no es una buena práctica usarlo como captura de errores en código, sin embargo es probable que lo encuentres en tu día a día como desarrollador.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Si miramos a profundidad el código no esta mal, sino que estamos agregando lógica adicional que esta afectando la legibilidad del código, y un de los principales objetivos que tenemos como programadores es escribir código limpio y legible. para los demás o tu yo del futuro. Imagina si hicieramos esto en códigos mas complejos y extensos.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;&lt;p&gt;La siguiente entrega de esta seria aborda el tema de como implementar tipado en Python, y como podemos mejorar la legibilidad del código y la productividad.
para verla da click en el siguiente botón.
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.dacadev.com/python/tipado/tipado-basico" class="btn btn-outline-primary " rel="" &gt;Tipado básico en Python&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item><item><title>Tipado en Python: Serie de DacaDev</title><link>https://blog.dacadev.com/python/tipado/00-serie-de-tipado/</link><pubDate>Thu, 08 Aug 2024 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/tipado/00-serie-de-tipado/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Descubre cómo el tipado en Python mejora la calidad de tu código, facilita la detección de errores y potencia la escalabilidad de tus proyectos de software. Explora nuestra serie de artículos en DacaDev.</description><media:content url="https://blog.dacadev.com/images/python/typing/serie/banner.png" medium="image" type="image/png"/><content:encoded>&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;, al ser un lenguaje interpretado y dinámicamente tipado, no incluye de forma nativa la gestión y manejo de tipos. Esta característica es extremadamente útil y práctica, especialmente para quienes están comenzando en el mundo del desarrollo de software.&lt;/p&gt;
&lt;p&gt;Sin embargo, a medida que los proyectos crecen, esta ventaja inicial puede convertirse en un desafío. La ausencia de un sistema de tipos explícito puede complicar la lectura del código, dificultar la depuración de errores y limitar la escalabilidad del proyecto.&lt;/p&gt;
&lt;p&gt;Por esta razón, ha surgido la iniciativa de implementar tipado en &lt;strong&gt;Python&lt;/strong&gt;. Con esta herramienta, los desarrolladores pueden tener un mayor control sobre los tipos de datos en su código, lo que permite capturar errores tempranos y mejorar la calidad del software desde las primeras etapas del desarrollo.&lt;/p&gt;
&lt;p&gt;En &lt;em&gt;DacaDev&lt;/em&gt;, hemos creado una serie de artículos que explican de manera detallada el tipado en &lt;strong&gt;Python&lt;/strong&gt;. A continuación, puedes acceder a cada uno de los artículos de la serie:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://blog.dacadev.com/python/tipado/introduccion"



 


&gt;Introducción al tipado en Python (teoría)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.dacadev.com/python/tipado/tipado-basico"



 


&gt;Tipado básico en Python&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title>Colecciones en Python: namedtuple()</title><link>https://blog.dacadev.com/python/colecciones/namedtuples/</link><pubDate>Tue, 14 May 2024 00:00:00 -0500</pubDate><guid>https://blog.dacadev.com/python/colecciones/namedtuples/</guid><dc:creator>Dacadev</dc:creator><category>python</category><description>Descubre cómo namedtuple() del módulo collections en Python optimiza el manejo de estructuras de datos con ejemplos prácticos. Aprende a mejorar la legibilidad y eficiencia de tu código con namedtuple().</description><media:content url="https://blog.dacadev.com/images/programming/python/collections/namedtuples/banner.png" medium="image" type="image/png"/><content:encoded>
&lt;details class="table-of-content "&gt;
 &lt;summary&gt;
 
 Tabla de Contenido
 
 &lt;/summary&gt;
 &lt;nav id="TableOfContents"&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#qué-es-namedtuple"&gt;¿Qué es &lt;code&gt;namedtuple()&lt;/code&gt;?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#ejemplos-de-uso"&gt;Ejemplos de uso&lt;/a&gt;
 &lt;ol&gt;
 &lt;li&gt;&lt;a href="#crear-una-namedtuple"&gt;Crear una &lt;code&gt;namedtuple&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#crear-una-namedtuple-con-valores-por-defecto"&gt;Crear una &lt;code&gt;namedtuple&lt;/code&gt; con valores por defecto&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#controlar-el-renombramiento-de-los-campos"&gt;Controlar el renombramiento de los campos&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
 &lt;/li&gt;
 &lt;li&gt;&lt;a href="#las-namedtuples-son-clases"&gt;Las &lt;code&gt;namedtuples&lt;/code&gt; son Clases&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="#por-qué-usar-namedtuples"&gt;¿Por qué usar &lt;code&gt;namedtuples&lt;/code&gt;?&lt;/a&gt;&lt;/li&gt;
 &lt;/ol&gt;
&lt;/nav&gt;
&lt;/details&gt;





 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;En este artículo, conocerás la función &lt;code&gt;namedtuple&lt;/code&gt; del módulo &lt;code&gt;collections&lt;/code&gt; de la biblioteca estándar de &lt;strong&gt;Python&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="qué-es-namedtuple"&gt;¿Qué es &lt;code&gt;namedtuple()&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;namedtuple()&lt;/code&gt; es una función que retorna una nueva clase, la cual permite acceder a los valores de una tupla tanto por índice como a través de un nombre definido al crear la tupla.&lt;/p&gt;
&lt;p&gt;Primero, examinaremos la firma de la función para entender cómo funciona y, posteriormente, analizaremos por qué y cuándo es beneficioso usarla.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#61afef;font-weight:bold"&gt;namedtuple&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;typename&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;field_names&lt;/span&gt;, &lt;span style="color:#56b6c2"&gt;*&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rename&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;False&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;defaults&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;module&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;None&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Esta firma revela cinco argumentos importantes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;typename&lt;/code&gt;: el nombre que se asignará a la nueva clase creada.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;field_names&lt;/code&gt;: ya sea un string o un iterable de strings que representan los nombres de los campos de la tupla. El orden de estos strings determina cómo se accederán los valores.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rename&lt;/code&gt;: un valor booleano que, si se activa, permite que la función reemplace nombres duplicados o conflictivos automáticamente.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;defaults&lt;/code&gt;: permite definir valores predeterminados para los campos de la tupla, asignando valores desde el final hacia el inicio de la lista de campos.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;module&lt;/code&gt;: un string que asocia la nueva tupla a un módulo específico.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Los argumentos definidos después de &lt;code&gt;*&lt;/code&gt; son argumentos que deben pasarse como &lt;code&gt;keyword arguments&lt;/code&gt; (es decir, como &lt;code&gt;nombre=valor&lt;/code&gt;), no de manera posicional.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id="ejemplos-de-uso"&gt;Ejemplos de uso&lt;/h2&gt;
&lt;h3 id="crear-una-namedtuple"&gt;Crear una &lt;code&gt;namedtuple&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Primero, veamos cómo crear una nueva tupla sencilla:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;collections&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Coordinates&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Coordinates&amp;#34;&lt;/span&gt;, [&lt;span style="color:#98c379"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Coordinates&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;x:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;y:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;y&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;z:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;z&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;x:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;[&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;], &lt;span style="color:#98c379"&gt;&amp;#39;y:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;[&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;], &lt;span style="color:#98c379"&gt;&amp;#39;z:&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;[&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El resultado de este código será:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ python main.py
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Coordinates&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;1, &lt;span style="color:#e06c75"&gt;y&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;2, &lt;span style="color:#e06c75"&gt;z&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;3&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;x: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; y: &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; z: &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;x: &lt;span style="color:#d19a66"&gt;1&lt;/span&gt; y: &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; z: &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Como observamos, creamos una nueva clase llamada &lt;code&gt;Coordinates&lt;/code&gt; con campos &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, y &lt;code&gt;z&lt;/code&gt;. Luego instanciamos &lt;code&gt;point_1&lt;/code&gt; y accedimos a sus valores tanto por nombre como por índice.&lt;/p&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Al declarar &lt;code&gt;point_1&lt;/code&gt;, los valores se asignan en el mismo orden en que se especifican en la tupla: primero &lt;code&gt;x&lt;/code&gt;, después &lt;code&gt;y&lt;/code&gt;, y finalmente &lt;code&gt;z&lt;/code&gt;.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h3 id="crear-una-namedtuple-con-valores-por-defecto"&gt;Crear una &lt;code&gt;namedtuple&lt;/code&gt; con valores por defecto&lt;/h3&gt;
&lt;p&gt;Definiendo valores por defecto, que deben ser iterables, podemos especificar los valores que se asignarán a los campos si no se proporcionan al crear la instancia:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;collections&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;UserData&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#98c379"&gt;&amp;#34;UserData&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&lt;span style="color:#98c379"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;age&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;email&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;country&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;defaults&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;example@mail.com&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;CO&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;david&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UserData&lt;/span&gt;( &lt;span style="color:#98c379"&gt;&amp;#34;David&amp;#34;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;28&lt;/span&gt;, )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;juan&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UserData&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Juan&amp;#34;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;24&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;juan@mail.com&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;david&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;juan&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El resultado de este código será:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;UserData&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;28, &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;example@mail.com&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;country&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;CO&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;UserData&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Juan&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;age&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;24, &lt;span style="color:#e06c75"&gt;email&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;juan@mail.com&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;country&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;CO&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Los valores por defecto se asignan de derecha a izquierda a los campos que no tienen valores asignados al crear la instancia.&lt;/p&gt;
&lt;p&gt;Pero debemos de tener en cuenta que si no pasamos todos los argumentos que no están definidos por defecto, la función lanzará un error.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;unknown&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UserData&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;unknown&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Traceback &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;most recent call last&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; File &lt;span style="color:#98c379"&gt;&amp;#34;/home/dacacode/dacadev/personal-blog/tempCodeRunnerFile.python&amp;#34;&lt;/span&gt;, line 9, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;unknown&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; UserData&lt;span style="color:#56b6c2"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ^^^^^^^^^^
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TypeError: UserData.__new__&lt;span style="color:#56b6c2"&gt;()&lt;/span&gt; missing &lt;span style="color:#d19a66"&gt;2&lt;/span&gt; required positional arguments: &lt;span style="color:#98c379"&gt;&amp;#39;name&amp;#39;&lt;/span&gt; and &lt;span style="color:#98c379"&gt;&amp;#39;age&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="controlar-el-renombramiento-de-los-campos"&gt;Controlar el renombramiento de los campos&lt;/h3&gt;
&lt;p&gt;Activando el argumento &lt;code&gt;rename&lt;/code&gt; como &lt;code&gt;True&lt;/code&gt;, la función automáticamente renombra campos duplicados o que sean palabras reservadas del lenguaje. Primero vamos a crear una tupla normal con nombres de campos que pueden entrar en conflicto.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;collections&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;dynamic_fields&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;def&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;arg&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;EspecialInfo&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;EspecialInfo&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;dynamic_fields&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;EspecialInfo&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Al ejecutar el código vas a obtener un error como el siguiente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Traceback &lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;most recent call last&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; File &lt;span style="color:#98c379"&gt;&amp;#34;/home/dacacode/dacadev/personal-blog/tempCodeRunnerFile.python&amp;#34;&lt;/span&gt;, line 4, in &amp;lt;module&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e06c75"&gt;EspecialInfo&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; namedtuple&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#34;EspecialInfo&amp;#34;&lt;/span&gt;, dynamic_fields&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; File &lt;span style="color:#98c379"&gt;&amp;#34;/home/dacacode/.pyenv/versions/3.11.5/lib/python3.11/collections/__init__.py&amp;#34;&lt;/span&gt;, line 398, in namedtuple
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; raise ValueError&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Type names and field names cannot be a &amp;#39;&lt;/span&gt;..&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ValueError: Type names and field names cannot be a keyword: &lt;span style="color:#98c379"&gt;&amp;#39;def&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pero si habilitamos la opcion de &lt;code&gt;rename&lt;/code&gt; el código funcionará, ya que la función se encarga de procesar esos casos.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;collections&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;dynamic_fields&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; [&lt;span style="color:#98c379"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;def&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;arg&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;EspecialInfoV2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;EspecialInfoV2&amp;#34;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;dynamic_fields&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;rename&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#e5c07b"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;EspecialInfoV2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;data&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;EspecialInfoV2&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;print&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;Hello, World!&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;data&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ahora si obtendremos un resultado positivo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;class &lt;span style="color:#98c379"&gt;&amp;#39;__main__.EspecialInfoV2&amp;#39;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;EspecialInfoV2&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;name&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;_1&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;print&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;arg&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;Hello, World!&amp;#39;&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;_3&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;&lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En donde podemos ver que los atributos que son &lt;code&gt;keywords&lt;/code&gt; y &lt;code&gt;duplicados&lt;/code&gt; han sido renombrados por valores posicionales, en este caso &lt;code&gt;_1&lt;/code&gt; y &lt;code&gt;_3&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="las-namedtuples-son-clases"&gt;Las &lt;code&gt;namedtuples&lt;/code&gt; son Clases&lt;/h2&gt;
&lt;p&gt;Por último, pero no menos importante, recuerda que el resultado de la función &lt;code&gt;namedtuple&lt;/code&gt; es una clase que hereda de &lt;code&gt;tuple&lt;/code&gt;, lo que significa que podemos usarla como cualquier otra clase. Por ejemplo, podemos usar la nueva clase como padre de otra para extender su funcionalidad:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;collections&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;Coordinates&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#34;Coordinates&amp;#34;&lt;/span&gt;, [&lt;span style="color:#98c379"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;class&lt;/span&gt; &lt;span style="color:#e5c07b"&gt;Point&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;Coordinates&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;def&lt;/span&gt; &lt;span style="color:#56b6c2;font-weight:bold"&gt;__add__&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;, &lt;span style="color:#e06c75"&gt;other&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#c678dd"&gt;return&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Point&lt;/span&gt;(&lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;x&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;other&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;y&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;other&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;y&lt;/span&gt;, &lt;span style="color:#e5c07b"&gt;self&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;z&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;other&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;z&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Point&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;2&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;point_2&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;Point&lt;/span&gt;(&lt;span style="color:#d19a66"&gt;4&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;5&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;6&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;point_2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e5c07b"&gt;print&lt;/span&gt;(&lt;span style="color:#e06c75"&gt;point_1&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;+&lt;/span&gt; &lt;span style="color:#e06c75"&gt;point_2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;El resultado de este código será:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Point&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;1, &lt;span style="color:#e06c75"&gt;y&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;2, &lt;span style="color:#e06c75"&gt;z&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;3&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Point&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;4, &lt;span style="color:#e06c75"&gt;y&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;5, &lt;span style="color:#e06c75"&gt;z&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;6&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Point&lt;span style="color:#56b6c2"&gt;(&lt;/span&gt;&lt;span style="color:#e06c75"&gt;x&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;5, &lt;span style="color:#e06c75"&gt;y&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;7, &lt;span style="color:#e06c75"&gt;z&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;=&lt;/span&gt;9&lt;span style="color:#56b6c2"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="por-qué-usar-namedtuples"&gt;¿Por qué usar &lt;code&gt;namedtuples&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;Una de las principales razones para usar las &lt;code&gt;namedtuple&lt;/code&gt; es la mejora de la legibilidad del código, ya que al momento los atributos para acceder a sus elementos es más fácil de entender que si lo hacemos por índice.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#abb2bf;background-color:#282c34;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#c678dd"&gt;from&lt;/span&gt; &lt;span style="color:#e06c75"&gt;collections&lt;/span&gt; &lt;span style="color:#c678dd"&gt;import&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;UserInfo&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;namedtuple&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;UserInfo&amp;#39;&lt;/span&gt;, [&lt;span style="color:#98c379"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;age&amp;#39;&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# Mejora la legibilidad&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; &lt;span style="color:#e06c75"&gt;UserInfo&lt;/span&gt;(&lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;28&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;mail@mail.com&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;name&lt;/span&gt; &lt;span style="color:#7f848e"&gt;# David&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;age&lt;/span&gt; &lt;span style="color:#7f848e"&gt;# 30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;&lt;span style="color:#56b6c2"&gt;.&lt;/span&gt;&lt;span style="color:#e06c75"&gt;email&lt;/span&gt; &lt;span style="color:#7f848e"&gt;# mail@mail.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#7f848e"&gt;# Debes tener en tu mente el orden de los campos, no es lo ideal!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;userRaw&lt;/span&gt; &lt;span style="color:#56b6c2"&gt;=&lt;/span&gt; {&lt;span style="color:#98c379"&gt;&amp;#39;David&amp;#39;&lt;/span&gt;, &lt;span style="color:#d19a66"&gt;28&lt;/span&gt;, &lt;span style="color:#98c379"&gt;&amp;#39;mail@mail.com&amp;#39;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;[&lt;span style="color:#d19a66"&gt;0&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;# David&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;[&lt;span style="color:#d19a66"&gt;1&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;# 30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e06c75"&gt;user&lt;/span&gt;[&lt;span style="color:#d19a66"&gt;2&lt;/span&gt;] &lt;span style="color:#7f848e"&gt;# mail@mail.com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Otros beneficios que encontramos es en la eficiencia del código, ya que al utilizar &lt;strong&gt;tuplas&lt;/strong&gt; (o &lt;code&gt;nametuples&lt;/code&gt;) encontramos que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Las &lt;strong&gt;tuplas&lt;/strong&gt; tienen mayor rendimiento al momento de ser creadas, debido a que son objetos inmutables y su alocación en memoria es mucho ams eficiente que las clasicas lsitas o diccionarios.&lt;/li&gt;
&lt;li&gt;Son ideales para procesar información que debe mantenerse constante durante todo su tiempo de vida, ya que las tuplas son inmutables.&lt;/li&gt;
&lt;li&gt;El tiempo de acceso a los elementos de la tupla es más rápido que las listas o los diccionarios.&lt;/li&gt;
&lt;/ul&gt;




 
 





 


&lt;div class="notice note"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="22" height="22" stroke-width="1.5" stroke="currentColor"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Note&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Esto no significa que las &lt;strong&gt;tuplas&lt;/strong&gt; sean mejores que otras estructuras de datos, esto depende de cada caso en particular y debes analizarlo antes de tomar una decisión.&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;





 
 





 


&lt;div class="notice info"&gt;
 &lt;div class="notice-head"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" width="22" height="22"&gt;
 &lt;path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" /&gt;
 &lt;/svg&gt;
 &lt;p&gt;Info&lt;/p&gt;
 
 &lt;/div&gt;
 &lt;div class="notice-body"&gt;&lt;p&gt;Para más información sobre &lt;code&gt;namedtuple&lt;/code&gt;, visita la documentación oficial en este &lt;a href="https://docs.python.org/3/library/collections.html#collections.namedtuple"




 target="_blank"
 


&gt;&lt;strong&gt;enlace&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
</content:encoded></item></channel></rss>