2017-07-07 24 views
5

Mam binarny dysk python zbudowany z discord.py, co oznacza, że ​​cały program działa wewnątrz pętli zdarzeń.Zbieranie wyników z python coroutines przed zakończeniem pętli

Funkcja, nad którą pracuję polega na wykonaniu kilkuset żądań HTTP i dodaniu wyników do ostatecznej listy. Wykonanie tych czynności zajmuje około dwóch minut, więc używam aiohttp do ich asynchronizacji. Powiązane części mojego kodu są identyczne z przykładami szybkiego startu w dokumentach aiohttp, ale program rzuca błąd RuntimeError: sesja jest zamknięta. Metodologia została zaczerpnięta z przykładu pod adresem https://pawelmhm.github.io/asyncio/python/aiohttp/2016/04/22/asyncio-aiohttp.html w sekcji "Pobierz wiele adresów URL".

async def searchPostList(postUrls, searchString) 
    futures = [] 
    async with aiohttp.ClientSession() as session: 
     for url in postUrls: 
      task = asyncio.ensure_future(searchPost(url,searchString,session)) 
      futures.append(task) 

    return await asyncio.gather(*futures) 


async def searchPost(url,searchString,session)): 
    async with session.get(url) as response: 
     page = await response.text() 

    #Assorted verification and parsing 
    Return data 

Nie wiem, dlaczego ten błąd pojawia się, ponieważ mój kod jest tak podobny do dwóch przypuszczalnie funkcjonalnych przykładów. Sama pętla zdarzeń działa poprawnie. Działa na zawsze, ponieważ jest to aplikacja bota.

Odpowiedz

4

W przykładzie, który łączyłeś, zbieranie wyników było w obrębie bloku async with. Jeśli robisz to na zewnątrz, nie ma gwarancji, że sesja nie zamknie się, zanim żądania zostaną złożone!

Przenoszenie instrukcji return wewnątrz bloku powinno działać:

async with aiohttp.ClientSession() as session: 
     for url in postUrls: 
      task = asyncio.ensure_future(searchPost(url,searchString,session)) 
      futures.append(task) 

     return await asyncio.gather(*futures) 
+0

Wow! To całkowicie zepsuło mój umysł. Hahaha, możesz powiedzieć, jak nowy jestem asynchroniczny. Dzięki za szybką pomoc! – user3896248