Python:替换模块类

时间:2018-05-30 07:44:25

标签: python function class python-module

我正在尝试替换类中定义的函数,以便在不更改实际代码的情况下修改其功能(如在内部工作中)。 我之前从未这样做过,因此在更换它时遇到了一些问题。 更改代码将让我访问我的python库中的包,这不是一个选项。

例如,如果模块名为testMOD

class testMOD(object):
      def testFunc(self, variable):
          var = variable
          self.something = var + 12

然后我将导入testMOD,定义一个类(mytest = testMOD()),并访问类testFunc中定义的函数,并将其更改为已定义的函数。

例如,

from somemodule import testMOD
mytest = testMOD()

def alternativeFunc(self, variable):
    var = variable
    self.something = var + 1.2

#problem here
mytest.testFunc = alternativeFunc

正如您所看到的,如果我只是使用我定义的函数手动覆盖(?)类中的函数,它将无法正常工作。 它没有给出任何语法错误,但是,问题是被替换的函数认为'self'是函数的另一个变量,并且说它需要另一个参数用于'变量'变量(我想这不是一个好名字。)

我想要做的是使替换函数与替换函数完全相同,但需要额外的代码或一些小的修改。但是,“自我”几乎不起作用,因为它应该在课堂上。 是否有办法正确实现定义的函数来替换导入类的函数?

4 个答案:

答案 0 :(得分:10)

我建议4种解决方案,从最差到最好(恕我直言),但当然这也取决于你的具体限制:

  1. 替换实例方法(1):我使用的函数是Python中的描述符,因此我可以使用__get__上的AlternativeFunc方法将其作为方法实例mytest并覆盖实例testFunc的{​​{1}}方法(不覆盖类方法):

    mytest
  2. 替换实例方法(2):这一次,我使用的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 比第一个解决方案更具可读性:

    types.MethodType
  3. 执行类方法的猴子修补。与第一种方法不同,它改变了类的任何实例的行为:

    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
    
  4. 创建一个继承自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 的类以覆盖该方法:

    testMOD

答案 1 :(得分:7)

你可以猴子补丁这个方法如下:

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)

输出:

original 24
alternative 13.2

答案 2 :(得分:1)

检查python中的类继承,创建自己的自定义类:

from somemodule import TestMOD

class YourCustomClass(TestMOD):

    # change the function
    def test_func(self, variable):
        #
        #

your_class = YourCustomClass()
your_class.test_func(x)

答案 3 :(得分:0)

这有点像黑客,你可以使用 lambda 函数

mytest.testFunc = lambda *args, **kwargs: alternativeFunc(mytest, *args, **kwargs)