Python中的Monkey Patching

Python中的Monkey Patching

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', >)]

如上面的代码中所示,上面的类中有两个方法 – init和addition。我们调用了add()方法并传入了20作为参数。它返回了30。我们已经定义了 MultiPatch 类,并且有 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提供了 ctype 模块,可以通过内存地址管理来改变对象的值。因此,不建议这样做,直接的内存操作是不安全且不一致的。可能对一个值起作用,对另一个值却不起作用。

结论

我们已经讨论了如何在Python中实现猴子补丁。但它具有一些缺点,应该小心使用。在应用程序设计中不适合使用,因为它区分了磁盘上的源代码和观察到的行为。开发者在调试时可能会感到困惑。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程