Python 函数引用

Python function references

我正在尝试模拟一个函数并修饰它的行为。为此,我必须获取原始函数行为,将其保存并将其添加到包装函数中。应如下所示:

@classmethod
def setUpClass(cls):
    def wrap_function(arg):
        return "potato" + original_function(arg)

    package.original_function = Mock(wraps= wrap_function)

此代码有效,但以下任何变体均无效。

1)

@classmethod
def setUpClass(cls):
    def wrap_function(arg):
        return "potato" + package.original_function(arg)

    original_function = Mock(wraps= wrap_function)

2)

@classmethod
def setUpClass(cls):
    def wrap_function(arg):
        return "potato" + package.original_function(arg)

    package.original_function = Mock(wraps= wrap_function)

3)

@classmethod
def setUpClass(cls):
    def wrap_function(arg):
        return "potato" + original_function(arg)

    original_function = Mock(wraps= wrap_function)

我都导入了

import package
from package import original_function

谁能向我解释为什么第一个有效,而其余的无效?

为什么第一个有效?

之所以有效,是因为您在模块级别对函数进行猴子修补,修改后的值将一直保留到模块保留在 sys.modules

基本上当你这样做时:

from package import original_function

这会在当前命名空间中添加对 original_function 对象的新引用,现在如果您执行以下操作:

package.original_function = 1

您正在更新该模块的命名空间以使 original_function 指向 1,但这并不意味着已经导入的 original_function 也应该更改。

为什么其他人失败了?

  1. original_function = Mock(wraps= wrap_function) 定义了一个新的局部变量,不会对 package.original_functionoriginal_function.

    产生任何影响
  2. package.original_function = Mock(wraps= wrap_function):模拟是正确的,但我们再次调用相同的模拟函数而不是 wrap_function 中的实际函数。

  3. original_function = Mock(wraps= wrap_function):和1一样,我们定义了一个局部变量,同样的函数也会被使用wrap_function,因为它在它的封闭范围内。