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:

  1. Replace the instance method (1): I use the fact that functions are descriptors in Python, so that I can use the __get__ method on AlternativeFunc to get it as a method of the instance mytest and overwrite the testFunc method of the instance mytest (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
    
  2. 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
    
  3. 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
    
  4. 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