1-Monkey Patch
about
Python3.6.8
what's a monkey patch
"monkey patch"一词来自于"guerrilla patch",是杂牌军、游击队的意思,而"guerrilla"的英语发音和"gorllia"大猩猩类似,但大猩猩哪有小猴子讨喜啊,所以,慢慢的"guerrilla patch"就变成了"monkey patch"。
monkey patch的定义
关于"monkey patch"这个术语的定义要取决于使用它的社区。在Ruby、Python和其他的动态编程语言中,"monkey patch"一词仅指在程序运行时,对类或者模块的动态修改或扩展。说白了,"monkey patch"就是在运行时动态的对已有代码进行修改,达到"hot patch"的目的。也可以实现Python中的装饰器的功能,在不修改源码的基础上进行功能扩展。
接下来,演示"monkey patch"在Python中的应用。
动态替换类的方法
如下代码:
class Foo(object):
def bar(self):
print("Foo bar method....")
foo = Foo()
foo.bar()
"""运行结果
Foo bar method....
"""
运行结果大家肯定没有异议。
那么现在,有一个更好的new_bar
方法替换原来的bar
方法,但由于原来的bar
被引用的太多,所以,希望不修改原来的代码,就能使用新的new_bar
方法,这时候就需要"monkey patch"了:
class Foo(object):
def bar(self):
print("Foo bar method....")
def new_bar(self):
print("Foo new bar method....")
foo = Foo()
# 使用 monkey patch 思想,偷偷的使用 new_bar 替换到原来的 bar 方法
Foo.bar = Foo.new_bar
# 但调用方式没有改变
foo.bar()
"""运行结果也有了改变
Foo new bar method....
"""
你也可以使用普通的函数来替换原来的bar
方法:
class Foo(object):
def bar(self):
print("Foo bar method....")
def new_bar(self):
print("Foo new bar method....")
def new_bar2(self):
print("function new bar 2....")
foo = Foo()
# 使用普通的函数替换掉原来的 bar 方法,但 bar 需要 self 参数,new_bar2在定义的时候也需要这个形参
Foo.bar = new_bar2
# 但调用方式没有改变
foo.bar()
"""运行结果也有了改变
function new bar 2....
"""
动态替换模块的方法
这个是"monkey patch"的典型应用场景:
import json
import ujson # pip install ujson
def monkey_patch_json():
json.__name__ = 'ujson'
json.dumps = ujson.dumps
json.loads = ujson.loads
monkey_patch_json()
s = "abc"
# 这里的json已经被替换为ujson了
print(json.__name__) # ujson
print(json.dumps(s)) # 调用的方法也被替换为 ujson.dumps 了
动态增加模块的方法
如果要对一个模块进行扩展,但又不修改原模块的内容,"monkey patch"也是一个很好的选择:
import datetime
import arrow # pip install arrow
now = arrow.now()
# shift 是 arrow 模块的方法
print(now.shift(months=2)) # 获取两个月后的当前时间
# datetime是shift方法的,现在可以通过 monkey patch 的思想,为 datetime 添加一个 shift 方法
datetime.shift = now.shift
print(datetime.shift(months=2))
that's all, see also:
Python Monkey patch猴子补丁 | 常用模块 | http://www.360doc.com/content/19/0527/07/58006001_838437018.shtml | Python Monkey patch猴子补丁 | https://en.wikipedia.org/wiki/Monkey_patch | Pyhon基础:Monkey Patch(猴子补丁) | 猴子补丁(Monkey Patch)