Większość implementacji coroutine w Pythonie (w tym dostarczone przez asyncio
i tornado
) zaimplementowano za pomocą generatorów. Tak było, ponieważ PEP 342 - Coroutines via Enhanced Generators umożliwiło wysyłanie wartości do działających obiektów generatora, co umożliwiło implementację prostych współprogramów. Corutines są technicznie są generatorami, są zaprojektowane do użycia w bardzo różny sposób. W rzeczywistości, PEP dla asyncio
explicitly states this:
współprogram jest generator, który następuje pewne konwencje.
asyncio.coroutine
jest generator. Całkiem dosłownie:
>>> import asyncio
>>> @asyncio.coroutine
... def mycoro():
... yield from asyncio.sleep(1)
...
>>> a = mycoro()
>>> a
<generator object mycoro at 0x7f494b5becf0>
Różnica polega na tym, jak te dwie rzeczy mają być używane. Próbuje iteracyjne nad asyncio.coroutine
jak zwykły generator nie będzie działać:
>>> 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
Najwyraźniej, nie jesteś oznaczało iteracyjne nad nim. Masz na celu tylko yield from
lub zarejestrować go w pętli zdarzeń asyncio
przy użyciu asyncio.create_task
lub asyncio.async
.
Tak jak wspomniałem wcześniej, możliwe było wdrożenie coroutines przy użyciu generatorów, ponieważ pojawił się PEP 342, który był długo przed asyncio
lub yield from
; funkcja ta została dodana w 2005 roku. asyncio
i yield from
dodają tylko te funkcje, które ułatwiają pisanie listów.
To pytanie jest teraz bardzo szerokie. Być może lepiej byłoby edytować go tak, aby obejmował tylko jeden lub dwa konkretne punkty (być może związane z tym, co chcesz zrobić z 'yieldFromRequests'?). Polecam lekturę [PEP 380] (https://www.python.org/dev/peps/pep-0380/), która wprowadziła 'yield from' do języka i [PEP 3156] (https: // www. .python.org/dev/peps/pep-3156 /), który wprowadził "asyncio". Pomiędzy tymi dwoma dokumentami należy odpowiedzieć na większość pytań. – dano
Również interesujące może być [PEP 492] (https://www.python.org/dev/peps/pep-0492), co jest propozycją uczynienia składni dla coroutines bardziej odrębną od składni dla generatorów - co oznacza nie więcej przy użyciu 'yield from' do implementacji coroutines. PEP nie została jeszcze zaakceptowana, choć wygląda na to, że wkrótce zostanie zaakceptowana (być może nawet w czasie dla Python 3.5). – dano
@dano Edytowałem pytanie. Pytam osobno. – item4