我发现最近总是跟一些python的标准库及第三方的库干上了。 平时没怎么关注,但只要一遇到问题,就想刨根问底分析源代码 ! 这样不仅解决当前问题,还能学习下功能模块是怎么实现的,另外还能学习别人的coder黑技巧.

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。 http://xiaorui.cc/?p=3248

前端时间写了一组连载的技术文章,主要是关于web框架的构成,别看标题有点大,内容虽然也有实质,但自己感觉还是不够深。  就这样web框架先暂停一个段落。

聊聊python的异步库gevent如何打猴子补丁, 他的用途是让你方便的导入非阻塞的模块,不需要特意的去引入。  我们暂时抛开gevent 猴子补丁代码实现,如果我们自己要实现module的替换, 可以说是” 模块补丁 ” 该怎么实现 ?  

第一种方法:
第一步, 直接干掉del sys.modules[xxx]  #可以省掉
第二步, __import__(xiaorui.cc)
第三步,sys.modules[xiaorui.cc] = __import__(xiaorui.cc)

结果跟我们预想的一样:


第二种:  偏软,显得不是很暴力:

上面的是咱们自定义模块替换方法,那么我们绕回主题 gevent pathc_all() 


上面的实例代码中我们有用到gevent monkey的补丁.  当我们执行patch_all()的时候,默认会把猴子所能支持的模块都打了补丁.

如果你不想打入threading的补丁怎么办 ? 解决的办法很简单,要不就是在gevent.monkey.patch_all(thread=False) , 要不就在patch_all后面追加import threading ,目的是覆盖前面的引入.

那么当我们执行gevent.monkey.pathc_all()的时候,gevent做了什么?

我们发现gevent patch_all针对模块的引入是有顺序的,另外文档也标明 ,这order很重要 ! 重要的原因是他们之间有依赖的关系。  举个简单的例子,subprocess是需要sys,os的支持的,如果sys.Popen是阻塞的,那么subprocess必阻塞.

这个函数的作用是python locals()当前环境中的变量赋值到saved字典里面.

通过getattr自省模式创建一个对象,然后通过__import__引入。

注意:
__import__跟import语句实现的功能是相同的,但__import__是一个函数,并且只接收字符串作为参数,所以它的作用就可想而知了。其实import语句就是调用这个函数进行导入工作的,import sys <==>sys = __import__(‘sys’) 。 通常在动态加载时可以使用到这个函数,比如你希望加载某个文件夹下的所用模块,但是其下的模块名称又会经常变化时,就可以使用这个函数动态加载所有模块了,最常见的场景就是插件功能的支持。

调用patch_item做可执行对象关联.

翻弄了下Gevent monkey的源码发现没多少好讲的,因为场景的原因,gevent的monkey实现比起咱们自定义的来说稍显的复杂。  下篇给大家分享下 gevent  hub.py core.py的实现,最近看了gevent的源码有些心得。

END



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品