Python:替换模块类中的函数

新手上路,请多包涵

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

更改代码将使我能够访问我的 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

# A problem here
mytest.testFunc = alternativeFunc

如您所见,如果我只是用我定义的函数手动覆盖(?)类中的函数,它将无法正常工作。

它没有给出任何语法错误,但是,问题是被替换的函数认为“self”是函数的另一个变量,并说它需要“variable”变量的另一个参数(我想那不是一个好名字)。

我想让替换函数与被替换函数完全相同,但有额外的代码或一些小的修改。但是,“自我”在课堂上几乎没有发挥应有的作用。

有没有办法正确实现定义的函数来替换导入类的函数?

原文由 Cody Chung 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

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

  1. 替换实例方法(1):我利用函数在Python中是描述符这一事实,这样我就可以使用 __get__ 方法在 AlternativeFunc 上获取它作为实例的方法 mytest 并覆盖实例的 testFunc 方法 mytest (不覆盖类方法):
    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

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

  1. 对类方法执行猴子修补。与第一个方法不同的是,它改变了类的任何实例的行为:
    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

  1. 创建一个继承自 testMOD 的类来覆盖方法:
    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

原文由 Laurent H. 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以按如下方式 _猴子修补_ 此方法:

 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

原文由 Reblochon Masque 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏