Можно ли рассматривать Python asyncio.coroutine как генератор?

Я погуглил python coroutine и увидел только генераторы (Почти почти во всех примерах используется yield без asyncio.)

Они действительно такие же?

В чем разница между asyncio.coroutine и генератором?


person item4    schedule 20.04.2015    source источник
comment
Этот вопрос сейчас немного широк. Возможно, вам будет лучше отредактировать его, чтобы просто охватить один или два конкретных момента (возможно, связанных с тем, что вы хотите сделать с yieldFromRequests?). Я бы порекомендовал прочитать PEP 380, который знакомит с языком yield from, и PEP 3156, который представил asyncio. Между этими двумя документами должны быть ответы на большинство ваших вопросов.   -  person dano    schedule 20.04.2015
comment
Также может представлять интерес PEP 492, в котором предлагается сделать синтаксис для сопрограмм, более отличных от синтаксиса для генераторов, что означает, что больше не нужно использовать yield from для реализации сопрограмм. PEP еще не принят, хотя, похоже, он будет принят в ближайшее время (возможно, даже во время Python 3.5).   -  person dano    schedule 20.04.2015
comment
@dano я отредактировал вопрос. Выкладываю вопрос отдельно.   -  person item4    schedule 20.04.2015
comment
Краткий ответ: да. Вот две ссылки: David Beazley's Coroutine Presentation and a Пример камня, ножниц, бумаги.   -  person Doug R.    schedule 20.04.2015
comment
Это важный вопрос, поскольку этот вопрос вызывает много путаницы. Таким образом, хотя asyncio.corountines технически являются генераторами, их применение на самом деле представляет собой совершенно другую проблему, и смешение двух подходов значительно усложняет изучение или применение любого из них.   -  person songololo    schedule 28.04.2015


Ответы (1)


Большинство реализаций сопрограмм в Python (включая те, что предоставлены asyncio и tornado) реализованы с использованием генераторов. Так было с тех пор, как PEP 342 – сопрограммы с помощью расширенных генераторов сделали это возможным. для отправки значений в работающие объекты-генераторы, что позволило реализовать простые сопрограммы. Технически сопрограммы являются генераторами, просто они предназначены для использования совсем по-другому. Фактически, PEP для asyncio явно заявляет следующее:

Сопрограмма — это генератор, который следует определенным соглашениям.

asyncio.coroutine является генератором. Буквально:

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

Разница, опять же, заключается в том, как эти две вещи предназначены для использования. Попытка перебрать asyncio.coroutine как обычный генератор не сработает:

>>> 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

Ясно, что вы не должны повторять это. Вам нужно только yield from его или зарегистрировать в цикле событий asyncio, используя asyncio.create_task или asyncio.async.

Как я упоминал ранее, сопрограммы можно было реализовать с помощью генераторов, начиная с PEP 342, который был задолго до появления asyncio или yield from; эта функция была добавлена ​​еще в 2005 году. asyncio и yield from просто добавляют функции, облегчающие написание сопрограмм.

person dano    schedule 20.04.2015