Как скоро, как вы используете yield
заявление, в теле функции, она становится генератором. Вызов функции генератора возвращает этот объект генератора. Это уже не нормальная функция; вместо этого вместо этого объект-генератор взял управление.
От yield
expression documentation:
Используя выражение yield
в определении функции достаточно, чтобы вызвать это определение, чтобы создать функцию генератора вместо нормальной функции.
Когда вызывается функция генератора, она возвращает итератор, известный как генератор. Затем этот генератор управляет выполнением функции генератора. Выполнение начинается, когда вызывается один из методов генератора.
В регулярной функции, вызов этой функции немедленно переключает управление этой функции тела, и вы просто тестируете результат функции, установленное это return
заявления. В функции генератора return
все еще сигнализирует о конце функции генератора, но в результате возникает исключение StopIteration
. Но пока вы не назовете один из четырех методов генератора (.__next__()
, .send()
, .throw()
или .close()
), тело функции генератора вообще не выполняется.
Для вашей конкретной функции f()
у вас есть регулярная функция, что содержит генератор. Сама функция ничего особенного, кроме того, что она выходит раньше, когда выполняется return 3
. Выражение генератора на следующей строке стоит само по себе, оно не влияет на функцию, в которой она определена. Вы можете определить его без функции:
>>> (i for i in range(10))
<generator object <genexpr> at 0x101472730>
Используя выражение генератор производит объект генератора, так же, как с помощью yield
в функции, то вызов функции, которая производит объект генератора. Таким образом, вы могли бы назвать g()
в f()
с тем же результатом, используя выражение генератора:
def f():
return 3
return g()
g()
еще функциональный генератор, но использовать его в f()
делает не сделать f()
функцию генератора тоже. Только yield
может это сделать.
Ваш метод g() неверен, вы не можете смешивать return и yield в той же функции, вы получаете сообщение об ошибке. Вставьте реальный код. –
@ LennartRegebro: Вы можете, по сути, комбинировать возврат и выход в ту же функцию. В Python 3.2 и ранее вы не можете вернуть * значение * (это 'SyntaxError'), но в Python 3.3 и выше вы даже можете это сделать. См. [Возврат в генераторе вместе с доходностью в Python 3.3] (http://stackoverflow.com/q/16780002) –
Ах, хорошо, не знал этого. –