首页 > 解决方案 > Python - 猴子补丁失败,为什么?

问题描述

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.如何解决?

标签: python-3.xmetaprogrammingpython-importmonkeypatchingpython-internals

解决方案


通过np.array = log(np.array)您更改“公共”名称np.array所指的功能。

但是np.asarraynumpy.core.numeric模块中定义,它有自己的“私有”名称来引用该函数。它不受修补公共名称的影响。

您必须修补私有名称:

np.core.numeric.array = log(np.array)

推荐阅读