2015-04-20 12 views
6

google python coroutine i zobaczył tylko generatory (prawie prawie wszystkie przykłady użyć yield bez asyncio.)Czy asyncio.coroutine w Pythonie można uważać za generator?

Są one naprawdę są takie same?

Jaka jest różnica między asyncio.coroutine a generatorem?

+0

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

+0

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

+0

@dano Edytowałem pytanie. Pytam osobno. – item4

Odpowiedz

3

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 asyncioexplicitly states this:

współprogram jest generator, który następuje pewne konwencje.

asyncio.coroutinejest 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.

Powiązane problemy