1、实例方法注入
运行时,动态给Python实例注入方法,也就是常说的方法注入
实例注入较安全,隔离性好;但每次创建实例都要手动执行一次注入。
python中使用 types.MethodType 来实现方法注入,它会自动绑定 self
import types
class App:
def hello(self):
print("original hello")
app1 = App()
def add_resource(self):
print(f"实例方法,self={self}")
app1.add_resource = types.MethodType(add_resource, app1)
2、类补丁
给类打补丁,也叫给类打猴子补丁。
为什么称为“猴子补丁”?
运行时不修改源码,直接动态替换、新增类的方法,直接修改类本身,改动会作用于该类所有实例,而不是只改单个对象,即该类所有已有、未来新建的实例都会带上这个方法。这种改动像猴子乱敲,虽然灵活但容易带来全局副作用。
类猴子补丁风险更大:全局污染,第三方代码遍历类方法属性时会看到这个新增方法,可能引发意外冲突
import types
class App:
def hello(self):
print("original hello")
app2 = App()
def class_patch_method(self):
print(f"类补丁方法,self={self}")
App.class_patch = class_patch_method
app2.class_patch()
3、实例方法注入-使用闭包
3.1 示例
class App:
def hello(self):
print("original hello")
app = App()
def make_func(instance):
def add_resource(*args,**kwargs):
print(f"闭包方式, instance={instance}")
return add_resource
app.add_resource = make_func(app)
app.add_resource()
3.2 什么是闭包?
- 闭包 = 内部函数 + 捕获了外层函数作用域里的变量,即使外层函数执行结束,变量依然保留。
- 内部函数记住外层的环境,后续调用内部函数时,还能访问当时捕获的变量。
- 闭包本质就是自带私有环境的函数,不用类也可以保存状态。
例如:
def outer(name):
def inner(): # 内部函数,捕获外层的name
print(name)
return inner
f = outer("laoer")
f()
输出:laoer
3.3 闭包优缺点
1)优点:
- 可以不写类就保存状态,代码轻量,适合少量状态场景。
- 外层变量形成私有环境,外部无法直接修改捕获的变量,实现简易封装。
- 适合回调函数、延迟执行、工厂函数(前面动态注入方法就用到)。
2)缺点
- 捕获的是变量引用,不能修改
- 调试麻烦:闭包变量藏在函数内部,查看、打印状态不方便。
- 内存不会及时释放,只要闭包对象存在,外层变量就无法被回收,容易内存占用偏高。
- 复杂状态管理时可读性差,比类难理解,不适合大量状态。



