В чем разница между 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;
.