В чем разница между raise StopIteration и оператором return в генераторах?

Мне любопытно различие между использованием raise StopIteration и оператором return в генераторах.

Например, существует ли разница между этими двумя функциями?

 def my_generator0(n): for i in range(n): yield i if i >= 5: return def my_generator1(n): for i in range(n): yield i if i >= 5: raise StopIteration 

Я предполагаю, что более «питонический» способ сделать это – второй способ (пожалуйста, поправьте меня, если я ошибаюсь), но насколько я вижу, оба способа StopIteration исключение StopIteration .

  • Самый короткий хэш в python для указания файлов кеша
  • Декоратор, который профилирует вызов метода и регистрирует результат профилирования
  • Переопределение специальных методов в экземпляре
  • Ошибка отправки формы, Flask
  • Как вызвать метод из другого плана в Flask?
  • Scrapy pipe spider_opened и spider_closed не вызываются
  • Как генерировать перестановки списка без «обратных дубликатов» в Python с использованием генераторов
  • Динамически привязать метод к экземпляру класса в python
  • 3 Solutions collect form web for “В чем разница между raise StopIteration и оператором return в генераторах?”

    Нет необходимости явно поднимать StopIteration поскольку это то, что делает оператор голого return для функции генератора – так что да, они одинаковы. Но нет, просто использование return более Pythonic.

    От: http://docs.python.org/2/reference/simple_stmts.html#the-return-statement (действителен для Python 3.2)

    В функции-генераторе оператор return не может включать выражение-list. В этом контексте голый возврат указывает на то, что генератор выполнен и вызовет остановку StopIteration.

    Или, как указывает @ Бакуриу, семантика генераторов несколько изменилась для Python 3.3, поэтому более подходящим является следующее:

    В функции генератора оператор return указывает на то, что генератор выполнен и вызовет повышение StopIteration. Возвращаемое значение (если оно есть) используется в качестве аргумента для построения StopIteration и становится атрибутом StopIteration.value.

    По состоянию на конец 2014 года return верен, а значение raise StopIteration для прекращения работы генератора находится в графике амортизации. Подробнее см. PEP 479 .

    Абстрактные

    Этот PEP предлагает изменение генераторам: когда StopIteration возникает внутри генератора, он заменяется на RuntimeError . (Точнее, это происходит, когда исключение вот-вот выйдет из фрейма стека генератора.) Поскольку изменение несовместимо назад, функция изначально вводится с использованием инструкции __future__ .

    принятие

    Этот PEP был принят BDFL 22 ноября …

    обоснование

    Взаимодействие генераторов и StopIteration в настоящее время несколько удивительно и может скрывать неясные ошибки. Неожиданное исключение не должно приводить к тонко измененному поведению, но должно вызывать шумную и легко отлаженную трассировку. В настоящее время StopIteration, случайно возникшее внутри функции генератора, будет интерпретироваться как конец итерации контуром, управляющим генератором.

    Это правда, они эквивалентны, за исключением того, что один читается, тогда как другой неясен. Это относится к самой первой версии генераторов (PEP 255 в разделе «Спецификация: возврат»), а последующие улучшения (например, сопрограммы) не меняют этого. yield from 3.3 yield from (PEP 380) расширяет его, чтобы return <expr> качестве синтаксического сахара для raise StopIteration(<expr>) , но это не меняет значения return; ,

    Python - лучший язык программирования в мире.