欢迎光临
我们一直在努力

【Python】实例方法注入和类补丁

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)缺点

  • 捕获的是变量引用,不能修改
  • 调试麻烦:闭包变量藏在函数内部,查看、打印状态不方便。
  • 内存不会及时释放,只要闭包对象存在,外层变量就无法被回收,容易内存占用偏高。
  • 复杂状态管理时可读性差,比类难理解,不适合大量状态。
赞(0)
未经允许不得转载:171主机测评 » 【Python】实例方法注入和类补丁
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址