Python如何将实例绑定方法解绑后重绑定到其他实例
方法绑定修改方案
1. 基础实现:修改已绑定方法的指向实例
你现有的测试代码用staticmethod的方式无法实现需求,Python的绑定方法本身封装了__func__(类上定义的原始未绑定函数)和__self__(当前绑定的实例)两个属性,调用时会自动把__self__作为第一个参数传入__func__,基于这个特性可以用两种方案实现重新绑定:
- 方案1:直接调用原始函数,手动传入目标实例
class A: def __init__(self, a): self.a = a def show(self): print(self.a) a1 = A(1) a2 = A(2) # 直接调用原始未绑定函数,手动传入a2作为self参数 a1.show.__func__(a2) # 输出2
- 方案2:用
types.MethodType生成绑定到新实例的新方法
import types a1 = A(1) a2 = A(2) # 将a1.show对应的原始函数绑定到a2上 new_show = types.MethodType(a1.show.__func__, a2) new_show() # 输出2
2. 适配记录回放场景的实现
你不需要存储方法名做映射,直接存储原始函数和调用参数即可,调整后的完整实现如下:
import types class Data: def __init__(self): self.caches = [] # 请勿在类外调用,用于记录调用流程 def add_cache(self, val): self.caches.append(val) def clean_cache(self): self.caches = [] def record(foo): def wrapper(self, *args, **kwargs): # 存储原始函数、调用参数,无需存方法名 self.add_cache({ 'func': foo, 'args': args, 'kwargs': kwargs }) return foo(self, *args, **kwargs) return wrapper # 回放方法:将当前实例的调用流程复现到target实例上 def simulate(self, target): for item in self.caches: # 直接调用原始函数传入目标实例即可 item['func'](target, *item['args'], **item['kwargs'])
测试用例:
class MyData(Data): def wrap(self): print('wrap') @Data.record def linear(self, least_square=True): print(f'执行linear,least_square={least_square},实例属性a={self.a}') # 原实例执行调用 origin = MyData() origin.a = 1 origin.linear(least_square=False) origin.linear() # 新实例回放调用 target = MyData() target.a = 2 origin.simulate(target)
运行输出:
执行linear,least_square=False,实例属性a=1 执行linear,least_square=True,实例属性a=1 执行linear,least_square=False,实例属性a=2 执行linear,least_square=True,实例属性a=2
内容的提问来源于stack exchange,提问作者Weilory
相关产品推荐
相关产品推荐

