В чем разница между 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 исключения.

3 ответов


нет необходимости явно повышать StopIteration Как вот что такое голый return оператор делает для функции генератора-так что да, они одинаковы. Но нет, просто используя return - это более подходящие для Python.

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

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

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

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


по состоянию на конец 2014 года return правильная и raise StopIteration для завершения работы генератора используется график амортизации. См.PEP 479 для полной информации.

Аннотация

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

принятие

эта ОПТОСОЗ была принята БДФЛ 22 ноября...

обоснование

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

...


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