python

Python中的yield、next和send

2017-10-03  本文已影响31人  mihope

当定义的方法和函数中有 yield 关键字,这个执行这个函数或者方法就将返回一个生成器对象,这个生成器对象可以被for循环迭代,也可以手动执行next或者send方法精准控制这个生成器的内部执行,我们看如下代码就可以简单理解 yield,next和send之间的关系和用法:

#!/usr/bin/env python
import types

def gen():
        print 'enter'
        a = yield 1 #StateA 
        print 'next'
        print a or 'a'
        b = yield 2 #StateB 
        print b or 'b'
        print 'next again'

g = gen()
print(type(g))
print('g isinstance types.GeneratorTyp : '+ str(isinstance(g, types.GeneratorType)))
print(g.next())

i=0
while(i>=0):
    i += 1
    print 'i:'+str(i)
    try:
        print(g.send('x'))
    except StopIteration:
        break

print('--------------')

g2 = gen()
print(type(g2))

for x in g2:
    print(x)


执行上述代码将打印如下信息:

<type 'generator'>
g isinstance types.GeneratorTyp : True
enter

i:1
next
x

i:2
x
next again
--------------
<type 'generator'>
enter

next
a

b
next again

详细解释一下执行过程
1、定义生成器函数
def gen()
2、获得迭代器对象,并赋值给g,同时我们打印g的类型,返回generator,可以看到我们类型判断为 generator
g = gen()
3、执行迭代器到到第一个yield处,此处打印1,然后迭代器就挂起了,等待下一次调用,我们暂时命名此出挂起状态为StateA。
print(g.next())
4、进入while循环,第一次执行循环,打印“i:1”,然后执行如下代码
print(g.send('x'))
上述代码将继续 StateA 状态开始执行,首先将字符串“x”发送到迭代器中,然后迭代器开始运行,将字符串“x”复制给变量a,然后打印出:

print 'next'  #next
print a or 'a' #x

接着运行到下一个 yield,返回yield值“2”到send函数,于是在while循环中就打印出了“2”,这时迭代器函数的状态运行到StateB
5、再次进入while循环,send函数将字符串“x”传递进迭代器,赋值给b,这样迭代器就打印出

print b or 'b'      #x
print 'next again'  #next again

然后由于迭代器中没有 yield 操作,将抛出一个 StopIteration 异常,我们接受到 StopIteration 异常就终止循环。
6、通过使用for循环来迭代一个迭代器对象更简单,不需要判断 StopIteration 异常就可以获取yield传出来的值,直接将其打印出

转载:Python中的yield,next和send

上一篇下一篇

猜你喜欢

热点阅读