Python猴子修补对象不按预期工作

时间:2014-01-10 16:25:01

标签: python object python-2.7 instance monkeypatching

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

我的代码:

# 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.py导入Math类时,如何修补它的添加方法。

1 个答案:

答案 0 :(得分:4)

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

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不同,self不会使用nameadd个参数,也不会print执行add。为了完成这项工作,请执行以下操作:

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)