Python 我可以修饰一个显式函数调用,比如np.sqrt()
我对python函数装饰器有一点了解。我想我的问题的答案是否定的,但我想确定一下。使用装饰器和Python 我可以修饰一个显式函数调用,比如np.sqrt(),python,numpy,decorator,python-decorators,Python,Numpy,Decorator,Python Decorators,我对python函数装饰器有一点了解。我想我的问题的答案是否定的,但我想确定一下。使用装饰器和x=np.array([1,2,3])的numpy数组,我可以覆盖x.sqrt()并更改行为。有什么方法可以在Python中重写np.sqrt(x) 用例:在上工作。希望能够在不更改当前使用的np.sqrt()的代码库的情况下获取不确定量的平方根 编辑: 我想修改quantities包中的np.sqrt,以便下面的代码可以工作(这三个代码都应该打印相同的结果,请注意使用np.sqrt()时的0不确定性)
x=np.array([1,2,3])
的numpy数组,我可以覆盖x.sqrt()
并更改行为。有什么方法可以在Python中重写np.sqrt(x)
用例:在上工作。希望能够在不更改当前使用的np.sqrt()
的代码库的情况下获取不确定量的平方根
编辑:
我想修改quantities
包中的np.sqrt
,以便下面的代码可以工作(这三个代码都应该打印相同的结果,请注意使用np.sqrt()时的0不确定性
)。我希望不要求最终用户修改他们的代码,而是在数量
包中正确包装/装饰np.sqrt()
。目前,许多numpy函数都经过修饰(请参见),但似乎只有在调用x.func()
时才起作用,而不是numpy.func(x)
时起作用
也许,正如布伦巴恩所说
np.sqrt = decorator(np.sqrt)
因为装饰器只是一个接受对象并返回修改对象的可调用对象。Monkeypatching
如果我正确理解了您的情况,那么您的用例实际上并不是关于装饰(以标准方式修改您编写的函数)
而是关于猴子修补术:
修改别人编写的函数而不实际更改该函数定义的源代码
“然后你需要什么”的成语是
import numpy as np # provide local access to the numpy module object
original_np_sqrt = np.sqrt
def my_improved_np_sqrt(x):
# do whatever you please, including:
# - contemplating the UncertainQuantity-ness of x and
# - calling original_np_sqrt as needed
np.sqrt = my_improved_np_sqrt
当然,这只能改变numpy.sqrt
的未来含义,
不是过去的。
因此,如果有人在上述内容之前导入了numpy
,并且已经以您希望影响的方式使用了numpy.sqrt
,那么您将失败。
(它们映射到的名称并不重要。)
但是在执行上述代码之后,numpy.sqrt
的含义
模块(无论是在它之前还是之后导入的numpy
)
将是my\u-improved\u-np\u-sqrt
,这些模块的创建者是否
不管你喜欢与否(当然,除非numpy.sqrt
正在其他地方进行)
注意
在所有情况下都会执行unmonkeypatching。装饰符适用于函数定义,而不是函数调用。如果函数已经定义,那么使用decorator就太晚了(尽管可以通过将包装函数指定给原始名称来实现相同的效果)。你能给出一个实际的代码示例,说明你想要做什么,以及你想要的效果是什么吗?提供了一个示例。我想包装np.sqrt()(和np.mean等),以便它与Quantilities包一起工作。大多数函数都有,但有些函数没有。我想我对装饰师太过分了。这个软件包包含了我还无法找到的装饰代码:我理解你的例子。但是我可以让
import-pkg
重载np.sqrt而不知道它将如何被调用(即从numpy-import*;sqrt();
或将numpy作为n;n.sqrt()导入)
。只有在numpy之后导入pkg
时,这才有效吗?@mankoff:实际上,只有在numpy之前导入pkg
时,这才有效。@BrenBarn,有些东西怎么能修改它还没有导入的东西呢?例如,如果不先导入它,pkg怎么能更改np.sqrt?(除了修改源代码,我认为这是不受欢迎的)@acushner:pkg
必须导入numpy并对其进行修改。它必须在numpy之前导入,因为导入numpy需要首先导入它,以确保它所做的任何包装都适用于导入numpy的所有其他内容。您好@Lutz,谢谢。是的,我想要(ed)修改其他人编写的函数。我注意到您的注释,不会这样做。我将习惯于以x.mean()
的方式编写代码,而不是以前的方式np.mean(x)
。只是出于好奇,无法重新加载(numpy)
处理在我的代码之前加载numpy的情况?好吧,Python有很多内置的东西,但是“一般来说,撤消和重做由某个模块完成的事情”不在其中。reload
可以改变未来,但不能改变过去。在您的情况下,reload
只会撤消对numpy.sqrt
的分配,而不会神奇地修改任何其他内容。
import numpy as np # provide local access to the numpy module object
original_np_sqrt = np.sqrt
def my_improved_np_sqrt(x):
# do whatever you please, including:
# - contemplating the UncertainQuantity-ness of x and
# - calling original_np_sqrt as needed
np.sqrt = my_improved_np_sqrt