Python中猴子补丁是什么?

运行时动态替换属性称为猴子补丁(Monkey Patch)。
为什么叫猴子补丁?
运行时更换属性与猴子无关。网上有两种关于猴子补丁起源的说法:
1.这个词最初是Guerilla Patch,杂牌军和游击队表明这部分不是原装的。在英语中,guerila的发音类似于gorlia(猩猩),然后写monkey(猴子)。
2.另一种解释是,原始代码被这种方式弄乱了(messing with it),英语称为monkeying about(调皮),所以叫Monkey Patch。
猴子补丁的名称有些莫名其妙,只要与“模块运行时更换的功能”相对应。
猴补丁的用法
1、运行时动态更换模块的方法
stackoverflow上有两个热门的例子,
consideraclassthathasamethodget_data.Thismethoddoesan externallookup(onadatabaseorwebAPI,forexample),andvarious othermethodsintheclasscallit.However,inaunittest,youdon't wanttodependontheexternaldatasource-soyoudynamically replacetheget_datamethodwithastubthatreturnssomefixeddata.
假设一个类有一种方法来get__data。这种方法做一些外部查询(例如查询数据库或Web) API等。),许多其他类别的方法都被调用了。然而,在单元测试中,您不想依赖外部数据源。所以你用哑方法替换了这种_data方法,哑方法只返回一些测试数据。
引用了另一个例子,Zope 在Monkey上,wiki对Monkey Patch解释:
fromSomeOtherProduct.SomeModuleimportSomeClass defspeak(self): return"ookookeeeeeeeee!" SomeClass.speak=speak
还有一个更实用的例子,使用了许多代码 import json,后来发现ujson的性能更高,如果你觉得每个文件的import json 改成 import ujson as json的成本更高,或者想测试用ujson代替json是否符合预期,只需在入口处添加:
importjson importujson defmonkey_patch_json(): json.__name__='ujson' json.dumps=ujson.dumps json.loads=ujson.loads monkey_patch_json()
2、运行时动态增加模块的方法
有很多这样的场景。例如,我们引用团队通用图书馆中的一个模块,并希望丰富模块的功能。除了继承,我们还可以考虑使用monkey Patch。
个人感觉Monkeyey Patch既方便又有搞乱源代码优雅的风险。
