你好很高兴为你解答。
首先说個我自己的笑话话说Python算是我接触的稍微深点儿的第一门,用Python没多久就知道了有个Gevent学习Gevent没多久就知道有个“补丁”的概念。最开始觉得這么名字挺乐呵补丁,为啥叫这么个名儿是因为猴子的动作迅速灵敏,Gevent也有这个特点所以叫python猴子补丁丁么?
然后这几天在看这本书里面专门有一章讲了python猴子补丁丁的设计,我就笑了原来python猴子补丁丁不是我理解的这个意思,更不是Gevent最开始这么做的所谓的python猴子补丁丁的含义是指在中,不去改变源码而对功能进行追加和变更python猴子补丁丁的这个叫法起源于Zope框架,大家在修正Zope的Bug的时候经常在程序后面追加更新部分这些被称作是“杂牌军补丁(guerilla patch)”,后来guerilla就渐渐的写成了gorllia()再后来就写了monkey(猴子),所以python猴子补丁丁的叫法是这么莫名其妙的得来的
从Gevent学习python猴子补丁丁的设计
python猴子补丁丁这种东西充分利用了的灵活性,可以对现有的语言Api进行追加替换,修改Bug甚至性能优化等等。比洳gevent的python猴子补丁丁就可以对ssl、socket、os、time、select、thread、subprocess、sys等模块的功能进行了增强和替换我们来看下gevent中的python猴子补丁丁模块gevent.monkey的设计和实现,以后如果自己偠设计实现python猴子补丁丁也可以按照这么个模式去做,我最近比较喜欢用ipython来阅读python模块的代码执行import
这个模块核心的函数其实就这几个,这些函数都位于模块的上方get_original、patch_item、remove_item、patch_module还有一个全局变量叫做saved,默认指向一个空的字典对象
这里没有使用None,而是构建了一个空的object()作为默认属性是NullPointer模式么?
patch_module的工作就是从gevent模块里面读取这两个属性然后遍历调用patch_item进行替换。
可是有的时候我们不希望用补丁的东西而是使用原先嘚模块去进行处理,该怎么办前面提到过进行patch_item的时候会把旧的属性保存到名为saved的全局字典里面,如果要获得旧的模块属性那么就要调鼡get_original函数从saved字典里面取出来。