Monkey Patching(猴子补丁) 是Python中一个引人注目的话题。Monkey Patching是一个指在运行时修改类或模块的术语。简单来说,可以在运行时更改类或模块的行为。让我们通过实际示例来理解这个概念。

当我们在大型项目上工作时,可能会遇到第三方库不正常工作的情况。因此,我们尝试在我们的项目中修改(或更改)它。这个过程称为Python中的Monkey Patching。通常,开发者会尽量避免使用它。但是,它是开发过程的一部分。

在Monkey Patching中,我们可以重新打开类并修改其行为。

我们将学习如何在Python代码中使用Monkey Patching。

我们知道Python是一种动态语言,类是可变的,因此我们可以在需要时修改它们。让我们通过以下示例来了解。

示例 -

import inspect  
  
  
class MonkeyPatch:  
    def __init__(self, n1):  
        self.n1 = n1  
  
    def add(self, other):  
        return (self.n1 + other)  
  
  
obj1 = MonkeyPatch(10)  
obj1.add(20)  
print(inspect.getmembers(obj1, predicate=inspect.ismethod))  

输出:

30
[('__init__', >), ('add', >)]

如上所示,在上面的代码中,上述类中有两个方法 - initadd。我们调用了 add() 方法并传递了20作为参数。它返回了30。我们定义了 MonkeyPatch 类,并在其中定义了 add() 方法。假设我们要向 MonkeyPatch 类添加一个新方法。

def divide(self, n2):  
    return(self.n1 - self.n2)  

要将 divide() 方法添加到 MonkeyPatch 类中,只需将 divide 函数分配给 MonkeyPatch

MonkeyPatch.divide = divide  

新创建的函数将在 MonkeyPatch 类中可用。让我们看下面的示例。

inspect.getmembers(obj, predicate=inspect.ismethod)  

输出:

[('__init__', >), ('subtraction', >)]

函数的动态行为

让我们看另一个示例,以更好地理解函数的动态行为。

示例 -

# new_monk.py  
class A:  
   def hello(self):  
      print (" The hello() function is being called")  

我们已经创建了一个模块,将在下面的代码中使用它来在运行时更改 hello() 函数的行为。

import new_monk  
def monkey_f(self):  
   print ("monkey_f() is being called")  
  
# replacing address of "func" with "monkey_f"  
new_monk.A.hello = monkey_f  
obj = new_monk.A()  
  
# calling function "func" whose address got replaced  
# with function "monkey_f()"  
obj.hello()  

输出:

monkey_f() is being called

更改内存地址

Python提供了 ctypes 模块,用于通过内存地址管理更改对象的值。因此,不建议进行直接内存操作,这是不安全的并且不一致。可能对一个值有效,而对另一个值无效。

结论

我们已经讨论了如何在Python中实现Monkey Patching。但是它具有一些缺点,应谨慎使用。在应用程序设计中不建议使用它,因为它会使源代码在磁盘上和观察的行为之间产生差异。在调试时,开发者可能会感到困惑。

标签: Tkinter教程, Tkinter安装, Tkinter库, Tkinter入门, Tkinter学习, Tkinter入门教程, Tkinter, Tkinter进阶, Tkinter指南, Tkinter学习指南, Tkinter进阶教程, Tkinter编程