Python3实例方法替换:保留原实例self的实现问题
解决Python实例方法替换的问题
这个问题我之前也碰到过,核心原因是Python的绑定方法机制在搞鬼,咱们一步步拆解:
为什么直接赋值objTwo.pSelf = objOne.pSelf不行?
当你通过实例objOne访问它的方法pSelf时,Python会自动把这个方法包装成一个绑定方法——简单说,这个方法已经和objOne绑定死了,它的self参数固定指向objOne。所以当你把它赋值给objTwo.pSelf后,调用objTwo.pSelf()时,实际操作的还是objOne的属性,完全达不到让objTwo用正确方法的目的。
正确的解决方案
这里有几种靠谱的方法,你可以根据场景选:
方案1:从正确类中获取未绑定方法
直接从SomeClassC(正确版本的类)中取出未绑定的方法,赋值给objTwo的实例属性。类的方法本身是未绑定的,当你通过实例调用它时,Python会自动把当前实例作为self传入:
# 替换objTwo的pSelf方法 objTwo.pSelf = SomeClassC.pSelf # 调用测试 objTwo.pSelf() # 此时self就是objTwo,会操作它的变量
方案2:用types.MethodType手动绑定
如果你想更明确地控制绑定关系,可以用types模块的MethodType,手动把正确的方法绑定到objTwo上:
import types # 把SomeClassC的pSelf方法绑定到objTwo objTwo.pSelf = types.MethodType(SomeClassC.pSelf, objTwo) # 调用测试 objTwo.pSelf()
方案3:用lambda包装(适合简单场景)
如果不想导入模块,也可以用lambda来包装正确的方法,手动传入objTwo作为self:
# 无参数的情况 objTwo.pSelf = lambda: SomeClassC.pSelf(objTwo) # 如果pSelf有其他参数,要处理可变参数 objTwo.pSelf = lambda *args, **kwargs: SomeClassC.pSelf(objTwo, *args, **kwargs) # 调用测试 objTwo.pSelf()
示例代码验证
咱们用一段完整代码演示效果:
class SomeClassC: def __init__(self): self.value = 100 def pSelf(self): print(f"正确版本:当前value = {self.value}") self.value += 1 class SomeClassB: def __init__(self): self.value = 200 def pSelf(self): print(f"有问题的版本:当前value = {self.value}") self.value -= 10 # 实例化对象 objOne = SomeClassC() objTwo = SomeClassB() # 错误操作演示 print("=== 错误赋值的结果 ===") objTwo.pSelf = objOne.pSelf objTwo.pSelf() # 输出的是objOne的value,因为self绑定了objOne print(f"objOne.value: {objOne.value}") # 变成101 print(f"objTwo.value: {objTwo.value}") # 还是200,没变化 # 正确操作(方案1) print("\n=== 方案1的结果 ===") objTwo.pSelf = SomeClassC.pSelf objTwo.pSelf() # 输出正确版本,操作objTwo的value print(f"objTwo.value: {objTwo.value}") # 变成201
运行这段代码就能清楚看到两种方式的区别啦。
内容的提问来源于stack exchange,提问作者jajabarr
相关产品推荐
相关产品推荐

