【问题标题】:Monkey-patching in PythonPython 中的猴子补丁
【发布时间】:2021-06-19 23:12:03
【问题描述】:

我有一个模块THIRDPARTY,其中包含各种类和功能:

def multi(n1, n2):
    result = n1 * n2
    return result

class Spam():

    def original_function(self, num1, num2):
        result = multi(num1, num2)
        new_result = result + result
        print(new_result)

我通过以下方式导入了模块: 将第三方导入为 tp

现在,我想将 Spam 类中的 original_function 替换为以下内容:

def original_function(self, num1, num2):
    result = multi(num1, num2) 
    new_result = num1 - num2
    print(new_result)

请注意original_function 中的不同数学运算。我试过但没有用:

tp.Spam.originalfunction = originalfunction

但是,它不继承其他类和函数(例如def multi)。

【问题讨论】:

  • original_function,无论是原始函数还是您的版本,都没有做任何有用的事情:它只是将某些内容分配给在函数末尾丢失的局部变量。你的意思是return num1 - num2self.result = num1 - num2,还是别的什么意思?
  • 我编辑了我的原始帖子以明确。函数的输出在这里并不重要。初始函数和新函数之间的区别在于数学运算符。
  • 创建一个 Spam 子类来做你想做的事(即实现它自己的 original_function() 方法),然后用这个派生类替换 THIRDPARTY 模块的 Spam 类。
  • 听起来您希望替换函数可以访问与原始函数相同的范围。它不是那样工作的。您的替换函数仍然存在于它定义的范围内。如果你想从 THIRDPARTY 访问函数,你必须像在任何其他情况下一样明确地这样做。

标签: python class monkeypatching


【解决方案1】:

我猜你还没有将multi() 导入为multi()。试试tp.multi() 而不是multi()


这是一个例子:

# ------in module.py file------

def multi(inp1, inp2):
    return inp1 + inp2

class A():
    def func1(self):
        print(multi(3, 4))
# ------in current file------

# what you're currently doing:

import module as md

def func1(self):
        print(multi(3, 4) + 10)


md.A.func1 = func1
class1 = A()
class1.func1()  # NameError: name 'multi' is not defined
# ------in current file------

# the fix:

import module as md

def func1(self):
        print(md.multi(3, 4) + 10)


md.A.func1 = func1
class1 = A()
class1.func1()

如果这不起作用,向我们展示实际功能可能会有所帮助,因为您可能会遗漏关键细节。

【讨论】:

    【解决方案2】:

    猴子补丁运行良好。我试着用 Flask 来做,我得到了结果。

    import flask
    
    def mult(self, n1, n2):
        print(n1 * n2)
    
    flask.Flask.before_request = mult
    
    obj = flask.Flask('name')
    obj.before_request(3, 4)  # 12
    

    【讨论】:

    • 问题依然存在。我编辑了我的原始帖子以使其清楚。
    猜你喜欢
    • 2012-12-18
    • 1970-01-01
    • 2011-04-15
    • 2017-10-05
    • 2016-09-01
    • 2012-09-16
    • 2020-01-09
    • 1970-01-01
    • 2012-04-21
    相关资源
    最近更新 更多