简体   繁体   中英

replace functions with a different function in python

I have a function called get_account(param1,param2) in run time I need to replace this function with the function mock_get_account(param1,param2) so when the system calls get_account(param1,param2) I need the mock_get_account(param1,param2) to be called instead.

I tried this code: package.get_account=self.mock_get_account package.get_account(x,y) but still the get_account runs instead of the mock_get_account I'm new to python and I don't know if this is even possible but I have seen the lamda function and I know that function programming is possible in python. Thanks Edit: if i do the following:

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

then every thing is ok, meaning the mock_get_account is called, but in mu code I the following code i do a post self.client.post(url, data=data, follow=True) that triggers the package.get_account and this is not working:

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)

meaning it calls the old function, also get_account(param1,param2) is defined in side a file, and is not a child function of a class and mock_get_account(self,param1,param2) is defined in a class Test and is called inside the Test.test_account - function

This is very opinionated and does not (directly) answer your question, but hopefully solves your problem.

A better practice is to use a subclass with your mock_get_account 's implementation override the parent get_account method, example below:

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

My guess is that the code implementing self.client.post has access to get_account through an import statement that looks like from package import get_account .

from package import get_account will first load package if it hasn't been already imported. Then it will look for a name get_account in that module, and whatever object that was bound to will be bound in the importing package's namespace, also under the name get_account . Thereafter the two names refer to the same object, but they are not the same name.

So if your mocking code comes along after this point, it sets the name get_account in package to instead refer to mock_get_account . But that'll only affect code that reads get_account from package again; anything that's already imported that name specially won't be affected.

If the code behind self.client.post instead had access only to package through import package , and was calling package.get_account it would work, because it's then only the object representing the package module that has been bound in the importing module's namespace. package.get_account would be reading an attribute of that object, and so would get whatever the current value is. If the from package import get_account appeared at function local scope rather than module scope, then this would behave similarly.

If I'm correct and your code is structured this way, then it's unfortunately not really package.get_account you need to rebind to a mock, but the get_account name in the module where self.client.post comes from (as well as any other modules which may call it).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM