在上一篇中,我们从生成器的基本认识与使用,成功过渡到了协程。
但一定有许多人,只知道协程是个什么东西,但并不知道为什么要用协程?换句话来说,并不知道在什么情况下用协程?
它相比多线程来说,有哪些过人之处呢?
在开始讲yield from 之前,我想先解决一下这个给很多人带来困惑的问题。
举个例子。
假如我们做一个爬虫。我们要爬取多个网页,这里简单举例两个网页(两个spider函数),获取HTML(耗IO耗时),然后再对HTML对行解析取得我们感兴趣的数据。
我们的代码结构精简如下:

我们都知道,get_html()等待返回网页是非常耗IO的,一个网页还好,如果我们爬取的网页数据极其庞大,这个等待时间就非常惊人,是极大的浪费。
聪明的程序员,当然会想如果能在get_html()这里暂停一下,不用傻乎乎地去等待网页返回,而是去做别的事。等过段时间再回过头来到刚刚暂停的地方,接收返回的html内容,然后还可以接下去解析parse_html(html)。
利用常规的方法,几乎是没办法实现如上我们想要的效果的。所以Python想得很周到,从语言本身给我们实现了这样的功能,这就是yield语法。可以实现在某一函数中暂停的效果。
试着思考一下,假如没有协程,我们要写一个并发程序。可能有以下问题
1)使用最常规的同步编程要实现异步并发效果并不理想,或者难度极高。
2)由于GIL锁的存在,多线程的运行需要频繁的加锁解锁,切换线程,这极大地降低了并发性能;
而协程的出现,刚好可以解决以上的问题。它的特点有
协程是在单线程里实现任务的切换的
利用同步的方式去实现异步
不再需要锁,提高了并发性能
yield from的用法详解
yield from 是在Python3.3才出现的语法。所以这个特性在Python2中是没有的。
yield from 后面需要加的是可迭代对象,它可以是普通的可迭代对象,也可以是迭代器,甚至是生成器。
简单应用:拼接可迭代对象#
我们可以用一个使用yield和一个使用yield from的例子来对比看下。
使用yield

使用yield from

由上面两种方式对比,可以看出,yield from后面加上可迭代对象,他可以把可迭代对象里的每个元素一个一个的yield出来,对比yield来说代码更加简洁,结构更加清晰。
复杂应用:生成器的嵌套#
如果你认为只是 yield from 仅仅只有上述的功能的话,那你就太小瞧了它,它的更强大的功能还在后面。
当 yield from 后面加上一个生成器后,就实现了生成的嵌套。
当然实现生成器的嵌套,并不是一定必须要使用yield from,而是使用yield from可以让我们避免让我们自己处理各种料想不到的异常,而让我们专注于业务代码的实现。
如果自己用yield去实现,那只会加大代码的编写难度,降低开发效率,降低代码的可读性。既然Python已经想得这么周到,我们当然要好好利用起来。
讲解它之前,首先要知道这个几个概念
1、调用方:调用委派生成器的客户端(调用方)代码
2、委托生成器:包含yield from表达式的生成器函数
3、子生成器:yield from后面加的生成器函数
你可能不知道他们都是什么意思,没关系,来看下这个例子。
这个例子,是实现实时计算平均值的。
比如,第一次传入10,那返回平均数自然是10.
第二次传入20,那返回平均数是(10+20)/2=15
第三次传入30,那返回平均数(10+20+30)/3=20

认真阅读以上代码,你应该很容易能理解,调用方、委托生成器、子生成器之间的关系。我就不多说了
委托生成器的作用是:在调用方与子生成器之间建立一个双向通道。
所谓的双向通道是什么意思呢?
调用方可以通过send()直接发送消息给子生成器,而子生成器yield的值,也是直接返回给调用方。
你可能会经常看到有些代码,还可以在yield from前面看到可以赋值。这是什么用法?
你可能会以为,子生成器yield回来的值,被委托生成器给拦截了。你可以亲自写个demo运行试验一下,并不是你想的那样。
因为我们之前说了,委托生成器,只起一个桥梁作用,它建立的是一个双向通道,它并没有权利也没有办法,对子生成器yield回来的内容做拦截。
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件
工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、全套PDF电子书
书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

四、入门学习视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

五、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。


网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。*
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
本文探讨了协程在Python中的应用,特别是与多线程和耗时IO操作的关系。通过实例解释协程如何实现暂停和恢复,以及yieldfrom的用法,对比了yield和yieldfrom的区别,强调了协程在提高并发性能和代码简洁性方面的优势。
851

被折叠的 条评论
为什么被折叠?



