感谢Shaumik Daityari帮助对本文进行同行评审。
当我们在 Python 中调用一个函数时,该函数通常会开始工作,直到遇到 a 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
无论之前回答“是”,次数都会增加?
这就是 Python 的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
如果您有一个返回序列的函数(例如,Excel 工作表中的行)并且您需要迭代序列而不同时将每个值都保存在内存中,则可以使用该函数。也就是节省内存。
yield
也可以在使用 iterables 时使用,我们有一个很难在函数之间传递的大列表。例如,Python 在itertools 模块中用于排列和组合的内置函数使用yield
.如果对Python有兴趣,想了解更多的Python以及AIoT知识,解决测试问题,以及入门指导,帮你解决学习Python中遇到的困惑,我们这里有技术高手。如果你正在找工作或者刚刚学校出来,又或者已经工作但是经常觉得难点很多,觉得自己Python方面学的不够精想要继续学习的,想转行怕学不会的, 都可以加入我们,可领取最新Python大厂面试资料和Python爬虫、人工智能、学习资料!微信公众号【Python大本营】等你来玩奥~