Python协程一点理解
2019-04-11 10:27:07来源:博客园 阅读 ()
yield
def test(): for i in 'abc': yield i for i in [1, 2, 3]: yield i if __name__ == '__main__': gen = test() print(gen.send(None)) print(gen.send(None)) print(gen.send(None)) print(gen.send(None)) print(gen.send(None)) print(gen.send(None)) print(gen.send(None))
def test(): for i in 'abc': yield i for i in [1, 2, 3]: yield i if __name__ == '__main__': gen = test() for i in gen: print(i)
使用for循环生成器,因为for循环可以捕捉StopIteration异常。
yield from
上面的代码也可以用yield from实现
def test(): yield from 'abc' yield from [1, 2, 3] if __name__ == '__main__': gen = test() for i in test(): print(i)
yield from
后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成器。
使用yield from实现实时计算器
def average_gen(): """ 子生成器 """ average = 0 total = 0 count = 0 while True: num = yield average if num is None: break count += 1 total += num average = total / count return average, count, total def proxy_gen(): """ 委派生成器 """ while True: average, count, total = yield from average_gen() print(f'平均值{average}, 计算{count}次, 总和{total}') def client(): """ 调用端 """ calc_average = proxy_gen() calc_average.send(None) # next(calc_average) # 预激活协程 print(calc_average.send(10)) print(calc_average.send(20)) print(calc_average.send(30)) calc_average.send(None) # 关闭协程 if __name__ == '__main__': client()
在委派生成器中的while True可以替换成for循环,循环的大小决定调用端可以calc_average.send(None)的次数(第一次预激活也计入)。
while True和for循环用来捕捉StopIteration异常,可以查看第一段代码。
示例
def average_gen(): """ 子生成器 """ average = 0 total = 0 count = 0 while True: num = yield average if num is None: break count += 1 total += num average = total / count return average, count, total def proxy_gen(): """ 委派生成器 """ for i in range(2): average, count, total = yield from average_gen() print(f'平均值{average}, 计算{count}次, 总和{total}') def client(): """ 调用端 """ calc_average = proxy_gen() calc_average.send(None) # next(calc_average) # 预激活协程 print(calc_average.send(10)) print(calc_average.send(20)) print(calc_average.send(30)) calc_average.send(None) # 关闭协程 print(calc_average.send(10)) print(calc_average.send(20)) print(calc_average.send(30)) calc_average.send(None) if __name__ == '__main__': client()
示例最后会抛出StopIteration异常。
因为在第二次calc_average.send(None)时,for循环捕捉了一次异常,进入了最后一次循环,在calc_average.send(None)时,for不能再次循环,不能处理StopIteration异常,故抛出。
原文链接:https://www.cnblogs.com/fifafengyang/p/10648886.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash