web-dev-qa-db-fra.com

Comment utiliser async / wait dans Python 3.5?

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time

async def foo():
  await time.sleep(1)

foo()

Je ne pouvais pas faire cet exemple simple mort à courir:

RuntimeWarning: coroutine 'foo' was never awaited foo()
51
smilingpoplar

L'exécution de coroutines nécessite une boucle d'événement . Utilisez la bibliothèque asyncio()) pour en créer une:

import asyncio

# Python 3.7+
asyncio.run(foo())

ou

# Python 3.6 and older
loop = asyncio.get_event_loop()
loop.run_until_complete(foo())

Voir aussi le chapitre Tâches et coroutines de la documentation asyncio . Si vous avez déjà une boucle en cours d'exécution, vous souhaitez exécuter simultanément plusieurs coroutines en créant une tâche (asyncio.create_task(...) in Python 3.7+, asyncio.ensure_future(...)) dans les anciennes versions).

Notez cependant que time.sleep() n'est pas un objet à attendre. Il retourne None pour que vous obteniez une exception après 1 seconde:

>>> asyncio.run(foo())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/.../lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete
    return future.result()
  File "<stdin>", line 2, in foo
TypeError: object NoneType can't be used in 'await' expression

Dans ce cas, utilisez plutôt asyncio.sleep() coroutine :

async def foo():
    await asyncio.sleep(1)

qui coopère avec la boucle pour permettre l'exécution d'autres tâches. Pour bloquer le code provenant de bibliothèques tierces n'ayant pas d'équivalent asyncio, vous pouvez exécuter ce code dans un pool d'exécuteurs . Voir Exécution d'un code de blocage dans le guide de développement asyncio.

73
Martijn Pieters

Si vous avez déjà une boucle en cours d'exécution (avec d'autres tâches), vous pouvez ajouter de nouvelles tâches avec:

asyncio.ensure_future(foo())

sinon vous pourriez avoir

The event loop is already running

erreur.

2
lenooh