Python - 猴子补丁失败,为什么?
Python - monkey patch fails, why?
我想从已安装的模块中对 f(*args, **kwargs)
进行猴子修补。我在自己的代码中使用装饰器的想法,但已安装模块中的其他方法无法正确调用 f
。
这是一个例子:
import numpy as np
def log(func):
def wrapper(*args, **kwargs):
print('logging')
return func(*args, **kwargs)
return wrapper
if __name__ == "__main__":
a1 = np.asarray([0, 1, 2])
print(f'a1={a1}')
a2 = np.array([0, 1, 2])
print(f'a2={a2}')
np.array = log(np.array)
a3 = np.asarray([0, 1, 2])
print(f'a3={a3}')
a4 = np.array([0, 1, 2])
print(f'a4={a4}')
输出为:
a1=[0 1 2]
a2=[0 1 2]
a3=[0 1 2]
logging
a4=[0 1 2]
我希望结果是:
a1=[0 1 2]
a2=[0 1 2]
logging
a3=[0 1 2]
logging
a4=[0 1 2]
因为 asarray
在源代码中调用了 array
。
我的问题是:
1. 为什么猴子补丁失败了? 2.如何解决?
通过 np.array = log(np.array)
,您正在更改 "public" 名称 np.array
所指的函数。
但是 np.asarray
是在 numpy.core.numeric
模块中定义的,它有自己的 "private" 名称来引用该函数。它不受修补 public 名称的影响。
您必须修补私人名称:
np.core.numeric.array = log(np.array)
我想从已安装的模块中对 f(*args, **kwargs)
进行猴子修补。我在自己的代码中使用装饰器的想法,但已安装模块中的其他方法无法正确调用 f
。
这是一个例子:
import numpy as np
def log(func):
def wrapper(*args, **kwargs):
print('logging')
return func(*args, **kwargs)
return wrapper
if __name__ == "__main__":
a1 = np.asarray([0, 1, 2])
print(f'a1={a1}')
a2 = np.array([0, 1, 2])
print(f'a2={a2}')
np.array = log(np.array)
a3 = np.asarray([0, 1, 2])
print(f'a3={a3}')
a4 = np.array([0, 1, 2])
print(f'a4={a4}')
输出为:
a1=[0 1 2]
a2=[0 1 2]
a3=[0 1 2]
logging
a4=[0 1 2]
我希望结果是:
a1=[0 1 2]
a2=[0 1 2]
logging
a3=[0 1 2]
logging
a4=[0 1 2]
因为 asarray
在源代码中调用了 array
。
我的问题是: 1. 为什么猴子补丁失败了? 2.如何解决?
通过 np.array = log(np.array)
,您正在更改 "public" 名称 np.array
所指的函数。
但是 np.asarray
是在 numpy.core.numeric
模块中定义的,它有自己的 "private" 名称来引用该函数。它不受修补 public 名称的影响。
您必须修补私人名称:
np.core.numeric.array = log(np.array)