web-dev-qa-db-ja.com

学習asyncio:「コルーチンは決して待たされなかった」警告エラー

Python=でasyncioを使用してスクリプトを最適化する方法を学びたいと思っています。私の例はcoroutine was never awaited警告を返します。それを理解して解決する方法を見つけるのに役立ちますか?

import time 
import datetime
import random
import asyncio

import aiohttp
import requests

def requete_bloquante(num):
    print(f'Get {num}')
    uid = requests.get("https://httpbin.org/uuid").json()['uuid']
    print(f"Res {num}: {uid}")

def faire_toutes_les_requetes():
    for x in range(10):
        requete_bloquante(x)

print("Bloquant : ")
start = datetime.datetime.now()
faire_toutes_les_requetes()
exec_time = (datetime.datetime.now() - start).seconds
print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")

async def requete_sans_bloquer(num, session):
    print(f'Get {num}')
    async with session.get("https://httpbin.org/uuid") as response:
        uid = (await response.json()['uuid'])
    print(f"Res {num}: {uid}")

async def faire_toutes_les_requetes_sans_bloquer():
    loop = asyncio.get_event_loop()
    with aiohttp.ClientSession() as session:
        futures = [requete_sans_bloquer(x, session) for x in range(10)]
        loop.run_until_complete(asyncio.gather(*futures))
    loop.close()
    print("Fin de la boucle !")

print("Non bloquant : ")
start = datetime.datetime.now()
faire_toutes_les_requetes_sans_bloquer()
exec_time = (datetime.datetime.now() - start).seconds
print(f"Pour faire 10 requêtes, ça prend {exec_time}s\n")

コードの最初のclassic部分は正しく実行されますが、後半は次のもののみを生成します。

synchronicite.py:43: RuntimeWarning: coroutine 'faire_toutes_les_requetes_sans_bloquer' was never awaited
15
Anthony Hervy

async関数内で_loop.run_until_complete_呼び出しを使用しないでください。このメソッドの目的は、同期コンテキスト内で非同期関数を実行することです。とにかく、コードを変更する方法は次のとおりです。

_async def faire_toutes_les_requetes_sans_bloquer():
    async with aiohttp.ClientSession() as session:
        futures = [requete_sans_bloquer(x, session) for x in range(10)]
        await asyncio.gather(*futures)
    print("Fin de la boucle !")

loop = asyncio.get_event_loop()
loop.run_until_complete(faire_toutes_les_requetes_sans_bloquer())
_

単独でfaire_toutes_les_requetes_sans_bloquer()を呼び出すと、明示的なawaitasyncコンテキスト内にいる必要があるため)で待機するか、イベントループに渡す必要があるfutureが作成されることに注意してください。 。放っておくと、Pythonはそれについて不平を言います。元のコードでは何もしません。

0
freakish