Python的生成器send()方法 & yield_from

生成器对象是一个迭代器。可是它比迭代器对象多了一些方法,它们包括send方法,throw方法和close方法。这些方法,主要是用于外部与生成器对象的交互。本文先介绍send方法。python

send

send方法有一个参数,该参数指定的是上一次被挂起的yield语句的返回值。这样提及来比较抽象,看下面的例子。函数

def MyGenerator():
value = (yield 1)
value = (yield value)


gen = MyGenerator()
print (next(gen))
print gen.send(2)
print gen.send(3)
输出的结果以下
1
2
Traceback (most recent call last): File "test.py", line 18, in <module> print gen.send(3) StopIteration

 

上面代码的运行过程以下。
当调用gen.next()方法时,python首先会执行MyGenerator方法的yield 1语句。因为是一个yield语句,所以方法的执行过程被挂起,而next方法返回值为yield关键字后面表达式的值,即为1。spa

当调用gen.send(2)方法时,python首先恢复MyGenerator方法的运行环境。同时,将表达式(yield 1)的返回值定义为send方法参数的值,即为2。这样,接下来value=(yield 1)这一赋值语句会将value的值置为2。继续运行会遇到yield value语句。所以,MyGenerator方法再次被挂起。同时,send方法的返回值为yield关键字后面表达式的值,也即value的值,为2。code

当调用send(3)方法时MyGenerator方法的运行环境。同时,将表达式(yield value)的返回值定义为send方法参数的值,即为3。这样,接下来value=(yield value)这一赋值语句会将value的值置为3。继续运行,MyGenerator方法执行完毕,故而抛出StopIteration异常。对象

注意一个要点:生成器函数在运行时候遇到yield时候就会挂起来,不会往下继续运行,直到有人调用.next()或者send()才会将值抛出而后往下运行。blog

总的来讲,send方法和next方法惟一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值经过参数设定,从而实现与生成器方法的交互。可是须要注意,在一个生成器对象没有执行next方法以前,因为没有yield语句被挂起,因此执行send方法会报错。例如generator

gen = MyGenerator()
print gen.send(2)

上面代码的输出为
Traceback (most recent call last):
File "test.py", line 16, in <module>
print gen.send(2)
TypeError: can't send non-None value to a just-started generator

固然,下面的代码是能够接受的it

gen = MyGenerator()
print gen.send(None)

 

由于当send方法的参数为None时,它与next方法彻底等价。可是注意,虽然上面的代码能够接受,可是不规范。因此,在调用send方法以前,仍是先调用一次next方法为好。io

yield from (功能十分强大)

  yield from 后面必须接一个iterable对象。ast

def gen_list(list):
    yield from list

d = gen_list(['frank', 'yangchao', 'liuliu'])
for i in d:
    print(i)

frank
yangchao
liuliu

  yield与yield from()的区别以下:yield from 能够将可迭代对象中的每一个对象迭代出来。

def yield_func(iterable):
    yield iterable
def yield_from_func(iterable):
    yield from iterable

yield_gen = yield_func(range(10))
for i in yield_gen:
    print(i)
yield_from_gen = yield_from_func(range(10))
for i in yield_from_gen:
    print(i)

range(0, 10)
0
1
2
3
4
5
6
7
8
9
相关文章
相关标签/搜索