【问题标题】:Python monkey patching objects not working as expectedPython猴子修补对象未按预期工作
【发布时间】:2023-03-08 23:27:01
【问题描述】:

我正在尝试学习 python 猴子补丁。我有一个简单的例子,我试图只修补单个实例而不是类本身。

我的代码:

# add.py
import types


class Math(object):
    def __init__(self):
        self.name = ''

    def add(self, x, y, name):
        self.name = name
        print 'calling from ', self.name
        return x + y

    def monkey_patch(self):
        add = self.add

        def squared_sum(x, y):
            return x**2 + y**2
        add = types.MethodType(squared_sum, self)


if __name__ == '__main__':
    math = Math()
    print math.add(3, 4, 'before monkey_patching')
    math.monkey_patch()
    print math.add(3, 4, 'after monkey_patching')

预期输出:

calling from  before monkey_patching
7
calling from  after monkey_patching
25

生成的输出:

calling from  before monkey_patching
7
calling from  after monkey_patching
7

谁能指出我哪里出错了。还有,当我从不同的文件中执行 add 方法时,我如何修改 add 方法,即当我从 add.py 导入 Math 类到不同的文件中时,我如何修改它的 add 方法。

【问题讨论】:

    标签: python object python-2.7 instance monkeypatching


    【解决方案1】:

    您的代码没有按照您的想法执行:

    def monkey_patch(self):
        add = self.add # add now points to self.add
        def squared_sum(x, y):
            return x**2 + y**2
        add = types.MethodType(squared_sum, self) # add now points to squared_sum
    # method ends, add and squared_sum are abandoned
    

    这实际上并没有改变 self.add。此外,squared_sum 不采用 selfname 参数,这与 add 不同,并且没有 add 那样的 print。要使这项工作充分发挥作用,请执行以下操作:

    def monkey_patch(self):
        def squared_sum(self, x, y, name):
            self.name = name
            print 'calling from ', self.name
            return x**2 + y**2
        self.add = types.MethodType(squared_sum, self) 
    

    在类定义之外打补丁:

    math = Math()
    
    def func(self, x, y, name):
        return x ** y
    
    math.add = types.MethodType(func, math)
    

    【讨论】:

    • 完美运行!有一个疑问。 self.add = types.MethodType(squared_sum, self) 显示在 init 警告之外定义的实例属性。现在如何将 self.add 移动到构造函数中?
    • 你在使用 PyCharm 还是什么?当然,您是“在__init__ 之外定义”,这就是您所做的全部意义;您可以忽略警告。
    • 没错!我正在使用 PyCharm!非常感谢!
    猜你喜欢
    • 2017-02-12
    • 2012-06-14
    • 2017-08-14
    • 1970-01-01
    • 2012-03-13
    • 2013-12-26
    • 2012-03-29
    • 2016-10-30
    • 1970-01-01
    相关资源
    最近更新 更多