当前位置: 首页 > 图灵资讯 > 行业资讯> 深入理解python中的yield

深入理解python中的yield

发布时间:2025-09-24 11:03:49

yield的英文单词意味着生产。当我第一次接触Python时,我感到非常困惑。我从来没有理解yield的用法。

只是大致知道yield可以用来为函数返回值塞数据,例如以下例子:

defaddlist(alist):
foriinalist:
yieldi+1

取出alist的每一项,然后取出ilist + 塞进去。然后通过调用取出每一项:

alist=[1,2,3,4]
forxinaddlist(alist):
printx

这确实是yield应用的一个例子

1. 包含yield的函数

如果你看到一个函数包含yield,这意味着这个函数已经是一个generator,它的执行将与其他普通函数有很多不同。例如,以下简单函数:

defh():
print'Tobebrave'
yield5
h()

可以看出,调用h()后,print 句子没有执行!这是yield,那么如何让printt呢? 语句执行情况如何?这就是后面要讨论的问题,通过后面的讨论和学习,你就会明白yield的工作原理。

2. yield是一种表达式

Python2.过去,yield是一个句子,但现在在2.5中,yield是一个表达式(Expression),比如:

m = yield 5

表达式(yield 5)返回值将赋值m,因此,认为 m = 5 这是错误的。那么如何获得呢?(yield 5)返回值怎么样?需要使用后面介绍的send(msg)方法。

3. 通过next()语句看原理

现在,让我们揭示yield的工作原理。众所周知,我们上面的h()调用后没有执行,因为它有yield表达式,所以我们让它通过next()语句执行。next()语句将恢复Generator执行,直到下一个yield表达式。例如:

defh():
print'WenChuan'
yield5
print'Fighting!'
c=h()
c.next()

c.next()调用后,h()开始执行,直到遇到yield。 所以输出结果:

Wen Chuan

当我们再次调用c时.next()在找到下一个yield表达式之前,它将继续执行。因为后面没有yield,所以会抛出异常:

WenChuan
Fighting!
Traceback(mostrecentcalllast):
File"/home/evergreen/Codes/yidld.py",line11,in<module>
c.next()
StopIteration

4. send(msg) 与 next()

在了解了next()如何执行包含yield的函数后,让我们来看看另一个非常重要的函数send(msg)。事实上,next()和send()在某种意义上是相似的,区别在于send()可以传递yield表达值,而next()不能传递特定值,只能传递none。因此,我们可以把它看作

c.next() 和 c.send(None) 功能是一样的。

让我们看看这个例子:

defh():
print'WenChuan',
m=yield5#Fighting!
printm
d=yield12
print'Wearetogether!'
c=h()
c.next()#相当于c.send(None)
c.send('Fighting!')#(yield5)表达式被赋予'Fighting!'

输出结果如下:

Wen Chuan Fighting!

需要提醒的是,第一次调用时,请使用next()语句或send(None),不要用send发送非none值,否则会出错,因为没有yield语句来接收值。

5. send(msg) 与 next()返回值

send(msg) 和 next()有返回值,它们的返回值非常特殊,返回的是下一个yield表达式的参数。例如yield 5,则返回 5 。在这里,你明白了什么吗?在本文的第一个例子中,通过for i in alist 遍历 Generator,事实上,alist每次都被调用.Next(),每次alist,.Next()返回值是yield的参数,也就是我们开始认为被压进去的东东。让我们继续上面的例子:

defh():
print'WenChuan',
m=yield5#Fighting!
printm
d=yield12
print'Wearetogether!'
c=h()
m=c.next()#m获得yield5的参数值5
d=c.send('Fighting!')#得到yield12的参数值12
print'Wewillneverforgetthedate',m,'.',d

输出结果:

WenChuanFighting!
Wewillneverforgethedate5.12

6. throw() 与 close()中断 Generator

中断generator是一项非常灵活的技能,可以通过throw抛出generatorexit异常来终止generator。Close()方法的功能是一样的。事实上,它在内部调用了throw(GeneratorExit)是的。我们看:

defclose(self):
try:
self.throw(GeneratorExit)
except(GeneratorExit,StopIteration):
pass
else:
raiseRuntimeError("generatorignoredGeneratorExit")
#Otherexceptionsarenotcaught

因此,当我们调用close()方法时,我们可以调用next()或send(msg)如果出现异常,就会抛出异常:

Traceback(mostrecentcalllast):
File"/home/evergreen/Codes/yidld.py",line14,in<module>
d=c.send('Fighting!')#得到yield12的参数值12
StopIteration

相关文章

Python中reduce函数和lambda表达式的学习

Python中reduce函数和lambda表达式的学习

2025-09-25
Python小白必学的面向对象

Python小白必学的面向对象

2025-09-25
一个例子解释python装饰器

一个例子解释python装饰器

2025-09-25
深入理解Python的set和dict

深入理解Python的set和dict

2025-09-25
Python中正则表达式的巧妙使用

Python中正则表达式的巧妙使用

2025-09-25
5分钟搞定Python中函数的参数

5分钟搞定Python中函数的参数

2025-09-25