Python如何给包打补丁
问题描述
当我们使用外部包的时候,有可能会发现源码效率不高或者有bug等问题,我们想要用自己的代码替换掉包中的部分代码。
解决方案
替换函数
源代码
# pkg.a
def func(a, b):
return a + b
def func_(a, b, c):
return func(a, b) * c
补丁代码
# patch.py
from pkg import a
def patch_func(a, b):
return a + b + 1
a.func = patch_func
"""
注:需要注意import方式
from pkg.a import func
func = patch_func
错误样例,这样func只会在patch模块内局部生效,而非全局生效
import pkg.a as a
a.func = patch_func
正确样例,这样替换也会全局生效
"""
使用补丁
from pkg.a import func_
print(func_(1, 2, 3)) # output: 9
import patch # 会运行patch.py代码,将func函数替换掉
print(func_(1, 2, 3)) # output: 12
替换类方法
源代码
# pkg.a
class A:
def __init__(a):
self.a = a
def afunc(self, b):
return self.a + b
补丁代码
# patch.py
from pkg.a import A
def patch_func(self, b):
return self.a + b + 1
A.afunc = patch_func
使用补丁
from pkg.a import A
print(A(1).afunc(2)) # output: 3
import patch # 会运行patch.py代码,将方法替换掉
print(A(1).afunc(2)) # output: 4
注意事项
需要注意使用patch代码后,后续任何代码在调用到被打补丁的代码后行为都会改变,包括你使用的其他第三方函数调用该代码,因此可能会引入隐形bug,导致很难排查。
不推荐在补丁中改变原函数输入输出、计算逻辑等,如果想改类方法行为则推荐使用继承。推荐使用补丁进行性能提升、bug修复。