Спасибо Shaumik Daityari за любезную помощь в рецензировании этой статьи.
Когда мы вызываем функцию в Python, функция обычно начинает работать, пока не встретит return
exception
Каждый раз, когда вы снова вызываете эту функцию, процесс начинается с нуля !
Скажите, что вы попросили человека отследить красные машины на дороге. Человек будет получать вопросы, спрашивая их, заметили ли они красную машину или нет, и тот, в свою очередь, ответит «да» или «нет». Если человек ответил «да», количество раз, когда красная машина была замечена, увеличится.
Давайте посмотрим, как мы можем сделать это в Python:
import time
def red_cars(answer):
n = 0
while True:
if answer == 'yes':
n = n + 1
return n
else:
return n
stop = time.time() + 5 * 60
while time.time() < stop:
answer = raw_input('Did you spot a red car on the road? ("yes" or "no"): ')
times = red_cars(answer)
print 'You have spotted ' + str(times) + ' cars so far!'
Если вы запустите программу, что вы заметите? Заметили ли вы, что количество раз для ответа «да» всегда ограничено 1
0
Вот где в игру вступает ключевое слово yield
yield
временно передаем управление вызывающей стороне и ожидаем продолжения с того момента, когда управление было передано.
Прежде чем дать решение вышеприведенному примеру, позвольте мне продемонстрировать очень простой пример, чтобы лучше проиллюстрировать, как работает yield
Скажем, у нас есть следующий простой скрипт на Python:
def step_by_step():
return 'step 1'
return 'step 2'
return 'step 3'
step = step_by_step()
for i in range (3):
print step
Если вы запустите скрипт, вы получите следующий вывод:
step 1
step 1
step 1
Теперь, если вместо этого мы используем yield
def step_by_step():
yield 'step 1'
yield 'step 2'
yield 'step 3'
step = step_by_step()
for i in range (3):
print step.next()
Вывод будет следующим:
step 1
step 2
step 3
Как видите, мы смогли создать серию значений, так как для каждого вызова функция продолжается с точки, где она выдает значение. Этот тип функции называется генератором . Такая функция создает итератор генератора , так как при каждом вызове метода next()
yield
Если мы вернемся к нашему основному примеру (красные машины), его можно записать следующим образом:
import time
def red_cars(answer = None):
n = 0
while True:
if answer=="yes":
n = n + 1
answer = yield n
else:
answer = yield n
car_color = red_cars()
car_color.next()
stop = time.time() + 5 * 60
while time.time() < stop:
answer = raw_input('Did you spot a red car on the road? ("yes" or "no"): ')
print 'You have spotted ' + str(car_color.send(answer)) + ' cars so far!'
Таким образом, как мы видим, yield
Однако есть и другие способы использования yield
Например, вы можете использовать yield
То есть для экономии памяти.
yield
Например, встроенные функции Python для перестановок и комбинаций в модуле itertools используют yield