Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以修饰一个显式函数调用,比如np.sqrt()_Python_Numpy_Decorator_Python Decorators - Fatal编程技术网

Python 我可以修饰一个显式函数调用,比如np.sqrt()

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不确定性)

我对python函数装饰器有一点了解。我想我的问题的答案是否定的,但我想确定一下。使用装饰器和
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
正在其他地方进行)

注意

  • 当你做一些奇怪的事情时,Python会变成一个奇怪的平台
  • 当你做一些奇怪的事情时,Python会变成一个奇怪的平台
  • 当你做一些奇怪的事情时,Python会变成一个奇怪的平台 这就是为什么猴子补丁通常不被认为是好的设计风格。 所以,如果你走这条路,一定要在显眼的地方宣布 在所有相关文件中

    哦,如果你不想修改其他代码 直接或间接地从您自己的方法执行,您可以 介绍一个在调用之前执行monkeypatching的装饰程序 和非monkeypatching(重新分配原始\u np\u 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