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

标签 python object python-2.7 instance monkeypatching

我正在尝试学习 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.py 导入 Math 类时,我如何猴子修补它的添加方法。

最佳答案

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

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 ,并且没有 printadd做。要使这项工作充分发挥作用,请执行以下操作:

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)

关于Python 猴子修补对象未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21049374/

相关文章:

python - 返回格式化的多行,末尾没有额外的空行

python - 查找图像中红色像素的坐标

javascript - Object.freeze 不会阻止对象被重新初始化?

c++ - 无法编译 C++ 代码 : invalid conversion from 'Node*' to 'int'

python - 战舰游戏 - if/else 问题

在线法官中来自 stdin 的 Python 输入

python - Google Cloud Platform,人工智能和机器学习产品,入门 : Training and Prediction with TensorFlow Estimator

python lmfit "object too deep for desired array"

android - 我怎样才能在android中打印对象列表

mysql - 如何在 mysql 的 python 列表中指定用于字符串的引号?