Wie kann man eine Reihe von Asynchrongeneratoren asynchron glätten?
Posted: 05 Jan 2025, 15:56
Ich muss eine Reihe von Webseiten durchsuchen. Diese Webseiten haben Adressen, die sich nur in der Seitennummer unterscheiden, und können daher parallel mit aiohttp verarbeitet werden.
Jetzt verwende ich Eine asynchrone Funktion zum Verarbeiten dieser Webseiten. Jeder Aufruf verwendet eine Adresse als Argument und gibt eine flache Liste von Zeichenfolgen zurück. Ich übergebe diese URLs alle auf einmal, ich möchte eine flache Liste aller Zeichenfolgen aus jedem Funktionsaufruf, die Reihenfolge dieser Zeichenfolgen ist mir egal, ich möchte eine Zeichenfolge, sobald sie ausgegeben wird, unabhängig davon, ob eine andere vorliegt Funktionsaufrufe sind abgeschlossen und ich möchte die Ergebnisse nicht verketten.
Ich kann es einfach nicht zum Laufen bringen.
Dies ist ein Minimales reproduzierbares Beispiel, das dasselbe veranschaulicht Problem:
Der obige Code wird ausgeführt, liefert jedoch nicht das erwartete Ergebnis. Es wartet 5 Sekunden statt 0,5 Sekunden und jedes Mal, wenn ich es ausführe, ist die Ausgabe dieselbe.
Ich habe Folgendes versucht:
Aber es funktioniert auch nicht:
Das funktioniert auch nicht:
Ich weiß, dass ich es so machen kann:
Aber wie ich oben ausdrücklich erwähnt habe, möchte ich asynchrone Generatoren verwenden.
Wie kann ich also gleichzeitig von asynchronen Generatoren profitieren?
Jetzt verwende ich Eine asynchrone Funktion zum Verarbeiten dieser Webseiten. Jeder Aufruf verwendet eine Adresse als Argument und gibt eine flache Liste von Zeichenfolgen zurück. Ich übergebe diese URLs alle auf einmal, ich möchte eine flache Liste aller Zeichenfolgen aus jedem Funktionsaufruf, die Reihenfolge dieser Zeichenfolgen ist mir egal, ich möchte eine Zeichenfolge, sobald sie ausgegeben wird, unabhängig davon, ob eine andere vorliegt Funktionsaufrufe sind abgeschlossen und ich möchte die Ergebnisse nicht verketten.
Ich kann es einfach nicht zum Laufen bringen.
Dies ist ein Minimales reproduzierbares Beispiel, das dasselbe veranschaulicht Problem:
Code: Select all
import asyncio
async def test(n):
await asyncio.sleep(0.5)
for i in range(1, 11):
yield n * i
async def run_test():
ls = []
for i in range(10):
async for j in test(i):
ls.append(j)
return ls
asyncio.run(run_test())
Ich habe Folgendes versucht:
Code: Select all
async def run_test():
ls = []
for t in asyncio.as_completed([test(i) for i in range(10)]):
for i in await t:
ls.append(i)
return ls
Code: Select all
TypeError: An asyncio.Future, a coroutine or an awaitable is required
Code: Select all
import asyncio
async def test(n):
await asyncio.sleep(0.5)
for i in range(1, 11):
yield n * i
async def run_test():
ls = []
for x in await asyncio.gather(*(test(i) for i in range(10))):
for j in x:
ls.append(j)
return ls
asyncio.run(run_test())
Code: Select all
TypeError: An asyncio.Future, a coroutine or an awaitable is required
Code: Select all
import asyncio
async def test(n):
await asyncio.sleep(0.5)
return [n * i for i in range(1, 11)]
async def run_test():
ls = []
for x in asyncio.as_completed([test(i) for i in range(10)]):
ls.extend(await x)
return ls
asyncio.run(run_test())
Wie kann ich also gleichzeitig von asynchronen Generatoren profitieren?