ProgramaciónDesarrollador de Python (asyncio/Backend)

¿Qué es un administrador de contexto Async (async context manager) en Python, cómo se implementa y dónde es indispensable?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

El administrador de contexto Async es un objeto que define los métodos asíncronos __aenter__ y __aexit__ y se utiliza en la construcción async with. Este administrador es necesario para abrir/cerrar recursos correctamente en funciones asíncronas: conexiones a bases de datos, archivos, sesiones, etc.

Ejemplo de implementación:

class AsyncDBConnection: async def __aenter__(self): self.conn = await async_db_connect() return self.conn async def __aexit__(self, exc_type, exc, tb): await self.conn.close() async def main(): async with AsyncDBConnection() as conn: await conn.query('SELECT 1')

El contexto asíncrono permite no bloquear el event loop con retrasos técnicos, aumentando la productividad de programas concurrentes.

Pregunta trampa.

¿Se puede usar el típico with dentro de un async def?

Respuesta: Sí, pero si las operaciones dentro del administrador de contexto utilizan awaitable (requieren await), se necesita exactamente async with. El típico with no soporta enter/exit asíncrono, bloqueará el event loop o fallará si se llama a await dentro de enter/exit.

Ejemplo:

async def foo(): with open('file.txt') as f: # esto está bien, la lectura es sincrónica data = f.read() # Pero no se puede await dentro de un contexto habitual, solo dentro de async with

Ejemplos de errores reales debido a la falta de conocimiento sobre las sutilezas del tema.


Historia

Proyecto: Servicio web con API asíncrona.

Problema: El administrador de conexión a la base de datos usó un with habitual, pero dentro se llamó a await. Esto provocó un error RuntimeError("No se puede usar 'await' fuera de una función async") y bloqueos del event loop en producción.


Historia

Proyecto: Chat en Websockets.

Problema: Al trabajar con conexiones no se cerraron los recursos websocket (se utilizó un administrador sincrónico habitual), lo que llevó a fugas de memoria y conexiones colgadas.


Historia

Proyecto: Cola de tareas asíncronas multihilo.

Problema: El administrador de tareas implementó incorrectamente __aexit__, olvidaron devolver awaitable. Debido a esto, la finalización de tareas no sucedía de manera garantizada, y parte de las tareas "quedaban colgadas" en el sistema.