gpt4 book ai didi

python - 我可以装饰一个显式函数调用吗,比如 np.sqrt()

转载 作者:太空宇宙 更新时间:2023-11-03 13:44:41 25 4
gpt4 key购买 nike

我对 python 函数装饰器有所了解。我认为我的问题的答案是否定的,但我想确定一下。使用装饰器和 x = np.array([1,2,3]) 的 numpy 数组,我可以覆盖 x.sqrt() 并更改行为。有什么方法可以覆盖 Python 中的 np.sqrt(x) 吗?

用例:处理 quantities package .希望能够在不更改当前使用 np.sqrt() 的代码库的情况下对不确定量求平方根。

编辑:

我想修改 quantities 包中的 np.sqrt 以便下面的代码可以工作(所有三个应该打印相同的结果,注意使用时的 0 不确定性np.sqrt())。我希望不要求最终用户修改他们的代码,而是在 quantities 包中正确包装/装饰 np.sqrt()。目前许多 numpy 函数都经过修饰(参见 https://github.com/python-quantities/python-quantities/blob/ca87253a5529c0a6bee37a9f7d576f1b693c0ddd/quantities/quantity.py ),但似乎仅在调用 x.func() 时有效,而不是 numpy.func(x) 时有效。

import numpy as np
import quantities as pq
x = pq.UncertainQuantity(2, pq.m, 2)
print x.sqrt()
>>> 1.41421356237 m**0.5 +/- 0.707106781187 m**0.5 (1 sigma)
print x**0.5
>>> 1.41421356237 m**0.5 +/- 0.707106781187 m**0.5 (1 sigma)
print np.sqrt(x)
>>> 1.41421356237 m**0.5 +/- 0.0 dimensionless (1 sigma)

最佳答案

猴子补丁

如果我对你的情况的理解正确,你的用例并不是真正的装饰(以标准方式修改编写的函数)而是关于猴子修补:修改别人编写的函数而不实际更改该函数定义的源代码。

你需要的成语是这样的

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的 future 含义,不是过去的。因此,如果有人在上述之前导入了 numpy 并且已经以您希望影响的方式使用了 numpy.sqrt,那么您就输了。(它们映射到 numpy 的名称无关紧要。)

但是上面的代码执行完之后,numpy.sqrt的意义在所有模块(无论是在它之前还是之后导入 numpy)将是 my_improved_np_sqrt 的那个,无论这些模块的创建者不管你喜不喜欢(当然,除非对 numpy.sqrt 进行更多的猴子修补)正在其他地方进行)。

注意

  1. 当你做奇怪的事情时,Python 可以成为一个奇怪的平台!
  2. 当你做奇怪的事情时,Python 可以成为一个奇怪的平台!
  3. 当你做奇怪的事情时,Python 可以成为一个奇怪的平台!

这就是为什么猴子补丁通常不被认为是好的设计风格。所以如果你走那条路,一定要在非常显眼的地方宣布它在所有相关文档中。

哦,如果你不想修改其他代码直接或间接地从你自己的方法执行,你可以引入一个在调用之前执行 monkeypatching 的装饰器和 un-monkeypatching(重新分配 original_np_sqrt)通话后将该装饰器应用于您所有有问题的功能。确保你在那个装饰器中处理异常,这样un-monkeypatching 在所有情况下都真正执行。

关于python - 我可以装饰一个显式函数调用吗,比如 np.sqrt(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22600365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com