python yield from的使用

来源:互联网 发布:两组数据的对比 编辑:程序博客网 时间:2024/05/16 12:09

yield from 可用于简化 for 循环中的 yield 表达式。

yield from x 表达式对 x 对象操作调用 iter(x),从中获取迭代器。因此,x 可以是任何可迭代的对象。

def chain(*its):for it in its:yield from itlist(chain(['a', 'b', 'c', 'd'], range(5), ['hello', 'world']))
---------------------------------------
yield from 的主要功能是打开双向通道,把最外层的调用方与最内层的子生成器连接起来, 这样二者可以直接发送和产出值, 还可以直接传入异常, 而不用在位于中间的协程中添加大量处理异常的样板代码。 有了这个结构, 协程可以通过以前不可能的方式委托职责

def get_sum():l = []while True:num = yieldif num is None:breakl.append(num)return {'sum': sum(l), 'list':l}def delegate(results):    while True:        result = yield from get_sum()        results.append(result)>>> results = []>>> summary = delegate(results)>>> next(summary)>>> for i in range(10):...     summary.send(i)... >>> summary.send(None)>>> for i in [3,6,1,3,4,5]:...     summary.send(i)... >>> summary.send(None)>>> results[{'sum': 45, 'list': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}, {'sum': 22, 'list': [3, 6, 1, 3, 4, 5]}]

yield from 的行为

  1. 子生成器产出的值都直接传给委派生成器的调用方(即客户端代码)。
  2. 使用 send() 方法发给委派生成器的值都直接传给子生成器。 如果发送的值是 None, 那么会调用子生成器的 __next__() 方法。 如果发送的值不是 None, 那么会调用子生成器的 send() 方法。 如果调用的方法抛出 StopIteration 异常, 那么委派生成器恢复运行。 任何其他异常都会向上冒泡, 传给委派生成器。
  3. 生成器退出时,生成器(或子生成器) 中的 return expr 表达式会触发 StopIteration(expr) 异常抛出。
  4. yield from 表达式的值是子生成器终止时传给 StopIteration异常的第一个参数

yield from 另外两个与异常和终止有关特性

  1. 传入委派生成器的异常, 除了 GeneratorExit 之外都传给子生成器的 throw() 方法。 如果调用 throw() 方法时抛出StopIteration 异常, 委派生成器恢复运行。 StopIteration 之外的异常会向上冒泡, 传给委派生成器。
  2. 如果把 GeneratorExit 异常传入委派生成器, 或者在委派生成器上调用 close() 方法, 那么在子生成器上调用 close() 方法, 如果它有的话。 如果调用 close() 方法导致异常抛出, 那么异常会向上冒泡, 传给委派生成器; 否则委派生成器抛出GeneratorExit 异常。

#StopIteration 之外的异常会向上冒泡, 传给委派生成器。def get_sum():    num = yield    raise Exception    return def delegate(results):    while True:        result = yield from get_sum()        results.append(result)print('end')>>> results = []>>> summary = delegate(results)>>> next(summary)>>> summary.send(1)Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 3, in delegate  File "<stdin>", line 3, in get_sumException
#子生成器抛StopIteration 异常,委派生成器恢复运行def get_sum():    num = yield    raise StopIteration    return numdef delegate(results):    while True:        result = yield from get_sum()        results.append(result)>>> results = []>>> summary = delegate(results)>>> next(summary)>>> for i in range(10):...     summary.send(i)... >>> >>> summary.send(None)>>> for i in [3,6,1,3,4,5]:...     summary.send(i)... >>> summary.send(None)>>> results[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]











原创粉丝点击