`send()`, `throw()` y `close()` en generadores Python
Cómo los tres métodos del protocolo de generador habilitan comunicación bidireccional y convierten cualquier función con yield en una corrutina primitiva.
Cómo los tres métodos del protocolo de generador habilitan comunicación bidireccional y convierten cualquier función con yield en una corrutina primitiva.
Cómo `yield` convierte una función en una máquina de estados y qué ocurre realmente en cada llamada a `next()`.
El protocolo iter/__next__/StopIteration que CPython ejecuta en cada bucle for, con sus implicaciones en diseño de clases y bugs de mutación.
Un iterable produce iteradores; un iterador guarda estado y avanza. Confundirlos rompe recorridos múltiples de formas silenciosas.
Diferencias estructurales, de memoria y semánticas entre NamedTuple y dataclass, con criterios claros para elegir según el caso de uso.
Cómo __slots__ elimina __dict__ en instancias CPython, cuánta memoria y velocidad ganas, y cuándo la limitación de diseño vale la pena.
Mecanismos internos de `@dataclass`, opciones como `frozen`, `slots` y `order`, y patrones con `field()`, `__post_init__` e `InitVar`.
Cómo usar Protocol para definir interfaces estructurales en Python sin herencia explícita, con soporte para type checkers y runtime_checkable.
Cómo usar `ABC` y `@abstractmethod` para definir contratos explícitos en jerarquías, incluyendo propiedades, classmethods y la diferencia práctica con Protocol.
Cómo estructurar objetos con composición en vez de herencia usando el patrón Strategy y Protocols en Python.