Python: replacing a function within a class of a module
I suggest 4 solutions, from the worst to the best (IMHO), but of course it also depends on your specific constraints:
Replace the instance method (1): I use the fact that functions are descriptors in Python, so that I can use the
__get__
method onAlternativeFunc
to get it as a method of the instancemytest
and overwrite thetestFunc
method of the instancemytest
(without overwriting the class method):class testMOD(object): def testFunc(self, variable): var = variable self.something = var + 12 print('Original:', self.something) def alternativeFunc1(self, variable): var = variable self.something = var + 1.2 print('Alternative1:', self.something) mytest1 = testMOD() mytest1.testFunc(10) # Original: 22 mytest1.testFunc = alternativeFunc1.__get__(mytest1, testMOD) mytest1.testFunc(10) # Alternative1: 11.2 mytestX = testMOD() mytestX.testFunc(10) # Original: 22
Replace the instance method (2): This time, I use
types.MethodType
which is a bit more readable than the first solution:import types class testMOD(object): def testFunc(self, variable): var = variable self.something = var + 12 print('Original:', self.something) def alternativeFunc1(self, variable): var = variable self.something = var + 1.2 print('Alternative1:', self.something) mytest1 = testMOD() mytest1.testFunc(10) # Original: 22 funcType = types.MethodType mytest1.testFunc = funcType(alternativeFunc1, mytest1) mytest1.testFunc(10) # Alternative1: 11.2 mytestX = testMOD() mytestX.testFunc(10) # Original: 22
Perform a monkey patching of the class method. Differently from the first method, it changes the behavior of any instance of the class:
class testMOD(object): def testFunc(self, variable): var = variable self.something = var + 12 print('Original:', self.something) def alternativeFunc2(self, variable): var = variable self.something = var + 1.2 print('Alternative2:', self.something) mytest2 = testMOD() mytest2.testFunc(10) # Original: 22 testMOD.testFunc = alternativeFunc2 mytest2.testFunc(10) # Alternative2: 11.2 mytestX = testMOD() mytestX.testFunc(10) # Alternative2: 11.2
Create a class inherited from
testMOD
to override the method:class testMODNew(testMOD): def testFunc(self, variable): var = variable self.something = var + 1.2 print('Alternative3:', self.something) mytest3 = testMODNew() mytest3.testFunc(10) # Alternative3: 11.2
You can monkey patch this method as follows:
class TestMOD(object):
def testFunc(self, variable):
var = variable
self.something = var + 12
print(f'original {self.something}')
def alternativeFunc(self, variable):
var = variable
self.something = var + 1.2
print(f'alternative {self.something}')
if __name__ == '__main__':
test_original = TestMOD()
test_original.testFunc(12)
TestMOD.testFunc = alternativeFunc
test_alternate = TestMOD()
test_alternate.testFunc(12)
Output:
original 24
alternative 13.2