PEP 0492 – Python 3.5 async keyword

PEP 0492 agrega la palabra clave async a Python 3.5.

¿Cómo se beneficia Python del uso de este operador? El ejemplo que se da para una coroutina es

 async def read_data(db): data = await db.fetch('SELECT ...') 

Según los documentos esto se consigue.

suspende [ing] la ejecución de read_data coroutine hasta que db.fetch awaitable finalice y devuelva los datos del resultado.

¿Esta palabra clave async realmente implica la creación de nuevos subprocesos o quizás el uso de un subproceso asíncrono reservado existente?

En el caso de que async use un hilo reservado, ¿es un solo hilo compartido cada uno por su cuenta?

No, las co-rutinas no involucran ningún tipo de hilos. Las co-rutinas permiten la multitarea cooperativa en el sentido de que cada co-rutina produce el control voluntariamente. Por otro lado, los hilos cambian entre unidades en puntos arbitrarios.

Hasta Python 3.4, era posible escribir co-rutinas usando generadores ; al usar el yield o el yield from expresiones en el cuerpo de una función, crea un objeto generador en su lugar, donde el código solo se ejecuta cuando se itera sobre el generador. Junto con las bibliotecas de bucles de eventos adicionales (como asyncio ), se podrían escribir co-rutinas que señalarían a un bucle de eventos que iban a estar ocupadas (esperando quizás la E / S) y que podría ejecutarse otra co-rutina en el mientras tanto:

 import asyncio import datetime @asyncio.coroutine def display_date(loop): end_time = loop.time() + 5.0 while True: print(datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break yield from asyncio.sleep(1) 

Cada vez que el código anterior avanza al yield from asyncio.sleep(1) , el bucle de eventos es libre de ejecutar una co-rutina diferente, ya que esta rutina no va a hacer nada durante el siguiente segundo.

Debido a que los generadores se pueden usar para todo tipo de tareas, no solo para las co-rutinas, y porque escribir una co-rutina con la syntax del generador puede ser confuso para los recién llegados, el PEP introduce una nueva syntax que hace más claro que usted está escribiendo un co -rutina.

Con el PEP implementado, la muestra anterior podría escribirse en su lugar como:

 async def display_date(loop): end_time = loop.time() + 5.0 while True: print(datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break await asyncio.sleep(1) 

El objeto de coroutine resultante todavía necesita un bucle de eventos para controlar las co-rutinas; un ciclo de eventos await en cada co-rutina, a su vez, lo que ejecutaría aquellas co-rutinas que actualmente no están await que algo se complete.

Las ventajas son que con el soporte nativo, también puede introducir una syntax adicional para admitir administradores de contexto asíncronos e iteradores. Entrar y salir de un administrador de contexto, o pasar por un iterador, puede convertirse en más puntos en su rutina que indica que se puede ejecutar otro código porque algo está esperando nuevamente.