如何用装饰器覆盖内部函数调用?

时间:2021-03-10 16:35:23

标签: python overloading decorator

我有一个这样的功能:

import math
import numpy as np
def mysin(x):
    return math.sin(x)

现在这很好,但我想修改函数,而不是调用 math.sin,它使用 numpy.sin。我的尝试是这个

def replace_math_with_numpy(func):
    math = np
    return func

然而,这不起作用:replace_math_with_numpy(mysin)([0.1,0.2]) 返回一个错误,表明我的装饰器没有工作。为什么它不起作用,我该如何修复我的装饰器 - 或者这是不可能的?

编辑:我想避免修改 mysin,因为实际上这只是一个 MWE,而 mysin 是一个有很多调用的库函数,在运行该函数时手动替换所有这些调用会非常繁琐。

2 个答案:

答案 0 :(得分:2)

只需向函数发送一个参数以指示要使用的库

import math
import numpy as np

def mysin(x, engine='math'):
    if engine == 'math':
        return math.sin(x)
    elif engine == 'numpy':
        return np.sin(x)
    else:
        raise NotImplementedError


if __name__ == "__main__":
    print(mysin(30))
    print(mysin(30, engine='numpy'))

答案 1 :(得分:0)

您可以使用 setattr 覆盖模块中的函数:

import math
import numpy as np

def replace_math_with_numpy(fName):
    setattr(math,fName,getattr(np,fName))


print(math.sin)                     # <built-in function sin>
replace_math_with_numpy("sin")
print(math.sin, math.sin == np.sin) # <ufunc 'sin'> True
相关问题