La fonction
enumerate()Copier le code
1 2 3 4 5 6 7 8 9 10 vowel = ["a", "e", "i", "o", "u", "y"] for i, letter in enumerate(vowel): print(i, letter) # 0 a # 1 e # 2 i # 3 o # 4 u # 5 y
Cela est très pratique, évitant ainsi de créer une variable avec un incrément dans la boucle.
Si on passe par une fonction asynchrone nous devons utiliser le mot clé
await
Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import asyncio async def vowel(): return ["a", "e", "i", "o", "u", "y"] async def main(): # Need to wrap in main function to manage async with asyncio for letter in await vowel(): # call coroutine with await keyword print(letter) asyncio.run(main()) # Call the loop # a # e # i # o # u # y
Et avec l'implémentation de
enumerate()Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import asyncio async def vowel(): return ["a", "e", "i", "o", "u", "y"] async def main(): # Need to wrap in main function to manage async with asyncio for i, letter in enumerate(await vowel()): print(i, letter) asyncio.run(main()) # Call the loop # 0 a # 1 e # 2 i # 3 o # 4 u # 5 y
Donc jusqu'ici tout se passe bien et on arrive à un fonctionnement attendu.
Si nous décidons maitenant que
vowel()yield
Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import asyncio async def vowel(): for letter in ["a", "e", "i", "o", "u", "y"]: yield letter async def main(): # Need to wrap in main function to manage async with asyncio for i, letter in enumerate(await vowel()): print(i, letter) asyncio.run(main()) # Call the loop # for i, letter in enumerate(await vowel()): # ^^^^^^^^^^^^^ # TypeError: object async_generator can't be used in 'await' expression
En effet
vowel()async for
Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # import asyncio # async def vowel(): # return ["a", "e", "i", "o", "u", "y"] # async def main(): # Need to wrap in main function to manage async with asyncio # for i, letter in enumerate(await vowel()): # print(i, letter) # asyncio.run(main()) # Call the loop import asyncio async def vowel(): for letter in ["a", "e", "i", "o", "u", "y"]: yield letter async def main(): # Need to wrap in main function to manage async with asyncio async for letter in vowel(): print(letter) asyncio.run(main()) # Call the loop
Maintenant essayons de mettre en place
enumerate()Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import asyncio async def vowel(): for letter in ["a", "e", "i", "o", "u", "y"]: yield letter async def main(): # Need to wrap in main function to manage async with asyncio async for i, letter in enumerate(vowel()): print(i, letter) asyncio.run(main()) # Call the loop # async for i, letter in enumerate(vowel()): # ^^^^^^^^^^^^^^^^^^ # TypeError: 'async_generator' object is not iterable
La fonction
enumerate()__iter__
__next__
Nous allons donc implémenter un fonctionnement similaire, à savoir une fonction asynchrone qui
await
Copier le code
1 2 3 4 5 async def async_generator_enumerate(generator, start=0): index = start async for coroutine in generator: yield index, coroutine index += 1
Et en reprenant l'exemple avec cette fonction
Copier le code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import asyncio async def vowel(): for letter in ["a", "e", "i", "o", "u", "y"]: yield letter async def main(): # Need to wrap in main function to manage async with asyncio async for i, letter in async_generator_enumerate(vowel()): print(i, letter) asyncio.run(main()) # Call the loop # 0 a # 1 e # 2 i # 3 o # 4 u # 5 y
Et voilà une implémentation de
enumerate()