yield的英语单词是指生产,刚接触Python的时候非常困惑,不知道yield的用法。
但是,我大致知道yield可以用于填充函数返回值的数据。 例如,以下示例:
efaddlist(alist ) :
for i in alist:
yield i 1
取出alist的各项,按入i 1。 然后,调用并取出每个项目。
a list=[ 1,2,3,4 ]
forxinaddlist(alist ) :
print(x )是
这确实是yield APP的一个例子。
包含yield的函数
假设你看到一个函数包含yield。 这意味着此函数已经是Generator,其执行与其他常见函数有很大不同。 例如,以下简单函数:
def h ) ) :
打印为be brave '
yield 5
h () )。
h ) )之后,可以看到print语句没有执行。 这就是yield。 那么,如何让print语句执行呢? 这就是接下来要讨论的问题。 通过稍后的讨论和学习,我们将了解yield的工作原理。
2. yield是表达式
在Python2.5之前,yield是一个语句,但在当前的2.5中,yield是一个表达式(Expression ),如下所示:
m=yield 5
公式yield 5的返回值代入m,所以认为m=5是错误的。 那么,如何获取(yield 5)的返回值呢? 需要后述的send(msg )方法。
next ) )通过句子看原理
那么,让我们弄清楚yield的结构吧。 我们知道我们上面的h (),因为有yield表达式,所以在被调用时不会执行。 因此,next ) )语句执行。 next ) )语句在下一个yield表达式之前恢复Generator的执行。 例如:
def h ) ) :
打印'汶川'
yield 5
打印文件!'
c=h () )。
c.next () )。
在调用c.next () (h ) )后,它将输出结果,直到遇到yield 5为止。
汶川
当我们再次调用c.next () )时,它会继续执行,直到找到下一个yield表达式。 因为后面没有yield,所以抛出异常:
汶川
好了!
跟踪后退(mostrecentcalllast ) :
file '/home/evergreen/codes/yi dld.py ',line 11,in
c.next () )。
停止解释
4.send(msg )和next ) )。
next ) )了解如何执行包含yield的函数后,我们来看另一个非常重要的函数send(msg )。 其实next (和send ) )在某种意义上起着类似的作用。 不同的是,send ) )可以传递yield表达式的值,但next ) )不能传递特定的值,只能传递None。 所以,我们应该
c.next (和c.send )的作用相同。
让我们来看看这个例子
def h ) ) :
打印'文川',
m=yield 5 # Fighting!
打印m
d=yield 12
打印' we are together!'
c=h () )。
c.next(#为c.send ) (none )
c.send('fighting!' () #(yield 5)表达式包含' Fighting!' 被赋予了力量
结果如下。
汶川加油!
在第一个调用中使用next (语句或send ) None。 不能使用send发送非None值。 发送非None值会导致错误,因为没有yield语句。
5.send(msg )和next ) )的返回值
send(msg )和next )具有返回值。 返回值是特殊的,返回以下yield表达式的参数: 例如,如果是yield 5,则返回5。 到此为止,你知道什么了吗? 在本文的第一个例子中,用for i in alist遍历Generator,但实际上每次都调用alist.Next () (每次都是alist.Next ) )的返回值是yield的参数继续上面的例子吧:
def h ) ) :
打印'文川',
m=yield 5 # Fighting!
打印m
d=yield 12
打印' we are together!'
c=h () )。
m=c.next(#m获取了yield 5的参数值5
d=c.send('fighting!' (d取得了yield 12的参数值12
print 'We will never forget the date ',m,'.',d
输出结果:
汶川加油!
We will never forget the date 5 . 12
6. throw (和close ) )中断生成器
中断生成器是一种非常灵活的技术,throw可以通过抛出生成器退出异常来退出生成器。 Close ) )方法的作用相同,但实际上在内部调用了throw(generatorexit )。 让我们看看:
defclose(self ) :
try:
self.throw(GeneratorExit )
except(generatorexit,停止身份) :
通过
else:
实时错误(generatorignoredgeneratorexit ) )。
# Other exceptions are not caught
因此,调用close (调用方法后为next ) )或send ) msg )时,会抛出异常。
跟踪后退(mostrecentcalllast ) :
file '/home/evergreen/codes/yi dld.py ',line 14,in
d=c.send('fighting!' (d取得了yield 12的参数值12
停止解释
7.Demo
defgen(:
打印(' 111 ) ) )。
m=yield 'ret 1'
我是print(m )
print(222 ) ) ) ) ) )。
n=yield 'ret 2'
打印(n )是
g=gen () )
print(g.next ) )
print-------- ' )
print(g.send('111over ' ) )
输出结果:
111
回复1
------------
11超重
222
回复2