用python中的不同函数替换函数

Posted

技术标签:

【中文标题】用python中的不同函数替换函数【英文标题】:replace functions with a different function in python 【发布时间】:2013-07-21 06:28:44 【问题描述】:

我有一个名为 get_account(param1,param2) 的函数 在运行时我需要用函数 mock_get_account(param1,param2) 替换这个函数 所以当系统调用 get_account(param1,param2) 我需要调用 mock_get_account(param1,param2) 来代替。

我试过这段代码: package.get_account=self.mock_get_account package.get_account(x,y) 但仍然运行 get_account 而不是 mock_get_account 我是 python 新手,我什至不知道这是否可能,但我已经看到了 lamda 函数,我知道函数编程在 python 中是可能的。谢谢 编辑: 如果我执行以下操作:

package.get_account=self.mock_get_account 
package.get_account(x,y) 

然后一切正常,这意味着调用了 mock_get_account,但是在 mu 代码中我下面的代码我做了一个 post self.client.post(url, data=data, follow=True) 触发 package.get_account 和这不起作用:

package.get_account=self.mock_get_account 
 package.get_account(x,y) 
 #the folowing call will trigger the package.get_account(x,y) function in a django url        #callback
 self.client.post(url, data=data, follow=True)

意味着它调用旧函数,get_account(param1,param2) 也定义在文件中,不是类的子函数,mock_get_account(self,param1,param2) 定义在类 Test 中并且是在 Test.test_account 内部调用 - 函数

【问题讨论】:

您所描述的应该可以正常工作。请给我们实际的代码和结果。 你能贴出一些实际的代码吗?像这样的猴子补丁在许多分布式包中使用,所以如果正确完成它确实可以工作。 如果我执行以下操作: package.get_account=self.mock_get_account package.get_account(x,y) 然后运行 ​​package.get_account 一切正常,在下面的代码中我会发布自我。触发 package.get_account 的 client.post(url, data=data, follow=True) 并且这不起作用,这意味着它打印旧函数,并且 get_account(param1,param2) 在文件中定义,而不是类的子函数和 mock_get_account(self,param1,param2) 在类 Test 中定义,并在 Test.test_account - 函数中调用 【参考方案1】:

这是非常固执的,并没有(直接)回答你的问题,但希望能解决你的问题。

更好的做法是使用带有mock_get_account 实现的子类覆盖父get_account 方法,示例如下:

class A(object):

    def get_account(self):
        return 1

    def post(self):
        return self.get_account()

class B(A):

    def get_account(self):
        return 2  # your original mock_get_account implementation

a = A()
print(a.get_account())

b = B()
print(b.post())  # this .post will trigger the overridden implementation of get_account

【讨论】:

【参考方案2】:

我的猜测是实现self.client.post 的代码可以通过类似于from package import get_account 的导入语句访问get_account

from package import get_account 将首先加载 package(如果尚未导入)。然后它将在该模块中查找名称get_account,并且绑定到的任何对象都将绑定在导入包的名称空间中,也在名称get_account 下。此后这两个名称指的是同一个对象,但它们不是同一个名称。

因此,如果您的模拟代码出现在之后,它会将package 中的名称get_account 设置为引用mock_get_account。但这只会影响再次从package 读取get_account 的代码; 已经特别导入该名称的任何内容都不会受到影响。

如果self.client.post 后面的代码只能通过import package 访问package,并且正在调用package.get_account,它会起作用,因为它只有代表package 模块的对象已绑定导入模块的命名空间。 package.get_account 将读取该对象的属性,因此将获得当前值。如果from package import get_account 出现在函数本地范围而不是模块范围,那么它的行为将类似。

如果我是正确的并且你的代码是这样构造的,那么不幸的是不是真的package.get_account 你需要重新绑定到一个模拟,而是self.client.post 来自的模块中的get_account 名称(以及就像任何其他可能调用它的模块一样)。

【讨论】:

以上是关于用python中的不同函数替换函数的主要内容,如果未能解决你的问题,请参考以下文章

Python替换函数输出不同的结果

用不同的代码替换 MicrosoftAjax.js 文件中的 eval()

python - 用两个不同列表中的值替换列表的布尔值[重复]

1个函数独立替换4个不同ID的innerHTML

尝试用不同语言写简单题的过程中的一些小发现

在 s3 python boto3 中替换文件