yield from是python3新增的語法
yield from gen_fun(), gen_fun是一個迭代器(列表, 字符串), yield from把函數分成了3個角色

5.png
1.委托生成器函數(可以理解為一個管道或者隊列), 包含有yield from gen_fun()語法, 獲取gen_fun()函數(子生成器)的返回值(return回來的值, 不是yield生成值).
2.子生成器函數gen_fun(), 包含有term = yield語法的函數, term是獲取調用方send過來的參數
- 調用方, 前面一章介紹過, 主要是send發(fā)送數據
下面使用流暢的python書中的代碼(簡化一下, 去除一下影響閱讀的代碼)
(https://github.com/fluentpython/example-code/blob/master/16-coroutine/coroaverager3.py)

6.png
代碼說明
- 創(chuàng)建一個Result的自定義數據結構, 包含count和average變量, 作為返回值
- 定義委托生成器grouper, yield from avgerager()啟動之后在此處暫停, results[key]的結果from于avgerager()子生成器的返回結果
- 定義子生成器avgerager(), 執(zhí)行方式和第一章的一樣, 當循環(huán)結束的時候, 返回結果給委托生成器, 賦值給results[key]
- 創(chuàng)建調用方main函數
- group = grouper(results, key) 創(chuàng)建grouper委托生成器對象.
- next(group) 激活委托生成器
- 循環(huán)data數據中的列表, send(value)把數據發(fā)送給子生成器的term
- 當列表中的數據發(fā)送完成之后, send(None), 終止子生成器, 子生成器終止之后, return計算出來的數據返回給委托生成器, 委托生成器中繼續(xù)循環(huán)重復上述4步,
- 完成列表中的數據之后print(results)
最后yield from替代嵌套for循環(huán)產出值
def chain(*args):
for i in args:
yield from i #委托生成器yield的值來自i迭代器的每一個值
if __name__ == '__main__':
print(list(chain(['A', 'B', 'C'], [1, 2, 3])))
下面是書中的一個列子, 可以看看
https://github.com/dabeaz/python-cookbook/blob/master/src/4/how_to_flatten_a_nested_sequence/example.py
拆分包含列表的列表
下一章介紹多線程與協程asyncio