2015-04-20 7 views
6

Ich googeln python coroutine und sah nur Generatoren (Fast fast alle Beispiele verwenden yield ohne asyncio.)Kann Python asyncio.coroutine als Generator gedacht werden?

Sind sie wirklich gleich?

Was ist der Unterschied zwischen asyncio.coroutine und einem Generator?

+0

Diese Frage ist ein bisschen jetzt breit. Es könnte besser sein, sie so zu bearbeiten, dass sie nur einen oder zwei bestimmte Punkte abdeckt (vielleicht in Bezug auf das, was Sie mit 'yieldFromRequests' machen wollen?). Ich würde empfehlen, [PEP 380] (https://www.python.org/dev/peps/pep-0380/) zu lesen, was "yield from" in die Sprache und [PEP 3156] (https: // www .python.org/dev/peps/pep-3156 /), die 'asyncio' einführten. Zwischen diesen beiden Dokumenten sollten die meisten Ihrer Fragen beantwortet werden. – dano

+0

Ebenfalls von Interesse könnte [PEP 492] (https://www.python.org/dev/peps/pep-0492) sein, die einen Vorschlag ist die Syntax für Koroutinen deutlicher von der Syntax für Generatoren zu machen - was bedeutet, Verwenden Sie nicht mehr "yield from", um Coroutinen zu implementieren. Das PEP wurde noch nicht akzeptiert, obwohl es so aussieht, als würde es bald akzeptiert werden (vielleicht sogar rechtzeitig für Python 3.5). – dano

+0

@dano Ich habe die Frage bearbeitet. Ich poste Frage separat. – item4

Antwort

3

Die meisten Coroutinimplementierungen in Python (einschließlich der von asyncio und tornado bereitgestellten) werden mithilfe von Generatoren implementiert. Dies war der Fall, da PEP 342 - Coroutines via Enhanced Generators es möglich gemacht hat, Werte in laufende Generatorobjekte zu senden, was die Implementierung einfacher Korutinen ermöglichte. Coroutines technisch sind Generatoren, sie sind nur entworfen, um in einer ganz anderen Art und Weise verwendet werden. In der Tat, der PEP für asyncioexplicitly states this:

A Koroutine ist ein Generator, die bestimmten Konventionen folgt.

asyncio.coroutine ist ein Generator. Ziemlich wörtlich:

>>> import asyncio 
>>> @asyncio.coroutine 
... def mycoro(): 
... yield from asyncio.sleep(1) 
... 
>>> a = mycoro() 
>>> a 
<generator object mycoro at 0x7f494b5becf0> 

Der Unterschied ist wiederum, wie die beiden Dinge verwendet werden sollen. Der Versuch, einen asyncio.coroutine wie ein gewöhnlicher Generator iterieren wird nicht funktionieren:

>>> next(a) 
Future<PENDING> 
>>> next(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in mycoro 
    File "/usr/lib/python3.4/asyncio/tasks.py", line 548, in sleep 
    return (yield from future) 
    File "/usr/lib/python3.4/asyncio/futures.py", line 349, in __iter__ 
    assert self.done(), "yield from wasn't used with future" 
AssertionError: yield from wasn't used with future 

Offensichtlich sind Sie darüber iterieren nicht gemeint. Sie sind nur yield from es ein oder registrieren sie mit der asyncio Ereignisschleife mit asyncio.create_task oder asyncio.async gemeint.

Wie bereits erwähnt, war es möglich, Coroutinen unter Verwendung von Generatoren zu implementieren, da PEP 342, das lange vor asyncio oder yield from kam; Diese Funktion wurde im Jahr 2005 hinzugefügt. asyncio und yield from nur Funktionen hinzufügen, die das Schreiben von Koroutinen einfacher machen.