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

时间:2013-07-22 13:33:13

标签: python lambda functional-programming mocking

我有一个名为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代码中,我在下面的代码中发布了一个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中调用 - 函数

2 个答案:

答案 0 :(得分:0)

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

更好的做法是使用子类,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

答案 1 :(得分:0)

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

from package import get_account如果尚未导入,则会先加载package。然后,它将在该模块中查找名称get_account,并且绑定到的任何对象将绑定在导入包的名称空间中,也名称为get_account。此后,这两个名称引用相同的对象,但它们的名称不同。

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

如果self.client.post背后的代码只能访问packageimport package,并且正在调用package.get_account它会起作用,因为它只会是package表示已绑定在导入模块命名空间中的package.get_account模块的对象。 from package import get_account将读取该对象的属性,因此将得到当前值的任何值。如果package.get_account出现在函数局部范围而不是模块范围,那么这将表现得相似。

如果我是正确的并且您的代码是以这种方式构建的,那么很遗憾,您不需要重新绑定到模拟get_account,而是self.client.post {{1}}来自的模块(以及可能调用它的任何其他模块)。