2023-09-26
python
00
请注意,本文编写于 431 天前,最后修改于 431 天前,其中某些信息可能已经过时。

目录

Python中扩展第三方模块的两种方式:Composition vs Monkey Patch
Composition(组合)
Monkey Patch
总结

Python中扩展第三方模块的两种方式
vs Monkey Patch

在Python开发中,我们经常需要使用第三方模块。为了自定义一些行为,我们可能需要对第三方模块进行扩展。本文将介绍两种常见的扩展方式:Composition(组合)Monkey Patch(猴子补丁),并比较两者的优缺点。

Composition(组合)

Composition的核心思想是,不直接修改第三方模块,而是将其封装在一个新类中,通过组合的方式实现扩展。

例如,有一个第三方模块math:

python
# math.py def add(x, y): return x + y def multiply(x, y): return x * y

我们可以这样通过组合扩展它:

python
import math class MathPlus: def __init__(self): self.math = math def add(self, x, y): return self.math.add(x, y) * 2 def multiply(self, x, y): return self.math.multiply(x, y)

使用MathPlus时:

python
math_plus = MathPlus() print(math_plus.add(2, 3)) # 10

这种方式的优点是:

  • 不需要修改第三方模块的代码,遵循开闭原则
  • 新增功能和原有功能分离清晰,扩展更加可控
  • 避免了模块之间的全局变量污染等问题
  • 符合组合优于继承的设计原则 缺点是:
  • 需要编写额外的包装代码,增加了一些复杂度
  • 对第三方模块的访问需要通过包装对象,可能带来少许运行时性能损失

Monkey Patch

Monkey Patch机制可以在运行时动态修改模块的属性和方法,实现对模块的扩展。

例如,可以这样扩展math模块:

python
import math # 新增一个add方法 def add(x, y): return x + y * 2 math.add = add # 修改既有的multiply方法 def new_multiply(x, y): return x * y * 2 math.multiply = new_multiply

使用时,math模块已经被扩展了:

python
print(math.add(2, 3)) # 8 print(math.multiply(2, 3)) # 12

这种方式的优点是:

  • 语法简单,可以快速方便地扩展第三方模块
  • 没有额外的封装代码,易于使用 缺点是:
  • 破坏了第三方模块的封装,不安全
  • 容易造成不同patch之间的冲突
  • 很难重置修改,不易维护
  • 多进程环境下会互相干扰
  • 第三方模块更新时扩展可能会失效

总结

  • Composition是一种非侵入式的扩展方式,修改是可控的,比较安全稳定。但需要额外的代码来组合模块。
  • Monkey Patch直接修改第三方模块,简单方便。但可能会导致难以预料的问题,不太安全。
  • Composition符合开闭原则,monkey patch破坏开闭原则。
  • Composition优先于继承,monkey patch可看作一种隐形的继承。
  • 对第三方模块的扩展,首先考虑Composition。如果只是临时的hack,可以使用monkey patch。
  • 复杂系统应优先使用Composition,只有非侵入式扩展才能使系统模块之间相对独立、稳定可控。
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:李佳玮

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!