async / await, la feature de dernière minute de Python 3.5 9
vendredi 24 avril 2015 à 20:47Ces mots clés vont-ils être introduits pour Python 3.5 alors qu’elle est déjà en alpha 4, et que la feature freeze est pour la prochaine version ? La release finale est prévue pour le 22 mai, ce qui est à peine un mois, pour une nouveauté formalisée début avril et toujours en draft.
J’avoue qu’à première vue, l’idée ne m’a pas enthousiasmé.
D’abord, parce que ça n’apporte pas grand chose de nouveau. Les coroutines, ça existe depuis un bail maintenant, et asyncio les exploite avec yield from
.
Pour résumer, la proposition est d’introduire deux mots clés tels que :
import asyncio @asyncio.coroutine def truc(): bidule() yield from machine_asynchrone() chose() |
Puisse être écrit :
async def truc(): bidule() await machine_asynchrone() chose() |
(Notez que la coloration syntaxique ne les prends pas en compte :))
Le PEP propose également l’introduction de deux syntaxes pour avoir des context managers et des boucles asynchrones: async with
et async for
Et ça ne m’a pas chauffé parce que :
- Je ne voyais pas l’intérêt d’ajouter des mots clés pour faire un truc qu’on peut déjà faire. Le faible nombre de key words dans Python est pour moi une feature.
- Il n’y a rien que ça permette qu’on ne pouvait pas faire avant.
- Ça me parait un peu fait à la dernière minute, introduit comme un voleur avant la release.
- C’est franchement moche le
async
avec un autre mot clé et ça pête toutes les attentes qu’on a eu sur la syntaxe du langage jusqu’ici : maintenant on a des qualificateurs, ce qu’on avait jamais eu avant. Ca ajouté aux type hintings, qui sont déjà très laids, c’est charger la mule.
Entre temps j’y ai réfléchi et avec le recul, je commence à voir de sérieuses qualités à cette proposition :
- On distingue clairement le code qui est pour créer des générateurs, et le code asynchrone. Ce sont des choses qui n’ont sémantiquement rien à voir, et utiliser
yield from
pour les deux rendait tout ça bien confus. - C’est moins à taper : pas besoin d’importer un décorateur de 3 km et l’apposer, et quand on a pas mal de point d’arrêt,
await
c’est moins chiant à tapper queyield from
et plus joli. - Ca évite pas mal de bug subtiles qui se glissent quand on utilise une coroutine pour la première fois sans comprendre tout le système. Par exemple si on vire tous les
yield from
d’une coroutine, c’est la merde, ce qui n’est pas le cas pour lesawait
. - Quand on fait une boucle sur un generateur on sait tout de suite si on va avoir un point d’arrêt ou non.
- Les mêmes mots clés sont utilisés dans d’autre langage, ce qui permet aux migrants de comprendre le principe bien plus vite qu’avec
yield
qu’il faut assimiler, et apprendre à distinguer dans ses deux formes.
Bref, async
et await
sont plus explicites, amènent moins de confusion, évitent des bugs et d’une manière générale permettent une compréhension plus rapide du code, mais également du concept de l’asynchrone en général, particulièrement pour les débutants.
Car j’avais en effet vu pas mal de gens ne rien piger aux coroutines.
Du coup, même si j’aimerais que le truc ne soit pas baclé et inséré à la va vite avant la bêta, je trouve finalement que c’est pas mal. La syntaxe n’est pas fantastique, mais je n’arrive pas à imaginer mieux (alors que clairement, les types hinting seraient 100x mieux dans la docstring avec le format existant pour sphynx), donc inutile de critiquer si on apporte pas de solution.