Python: replacing a function within a class of a module

后端 未结 3 1191
遥遥无期
遥遥无期 2020-12-13 11:35

I\'m trying to replace a function defined within a class in order to modify its function (as in inner workings) without changing the actual code. I\'ve never done this befor

相关标签:
3条回答
  • 2020-12-13 11:43

    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
    
    0 讨论(0)
  • 2020-12-13 11:49

    check class inheritance in python, to create your own custom class:

    from somemodule import TestMOD
    
    class YourCustomClass(TestMOD):
    
        # change the function
        def test_func(self, variable):
            #
            #
    
    your_class = YourCustomClass()
    your_class.test_func(x)
    
    0 讨论(0)
  • 2020-12-13 11:54

    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
      
    0 讨论(0)
提交回复
热议问题