重置属性后动态调用属性方法指向错误实例的问题解决
动态调用指向实例的问题
我定义了一个作为其他类属性的attributeClass,当容器类ContainerClass重置该属性后,直接调用属性类的方法会作用于新实例,但通过字典存储的动态调用却仍然作用于旧实例。请问如何确保动态调用能指向已重置后的属性实例?
示例代码
class attributeClass(): def __init__(self): self.dummy = 0 def printDummy(self): print('id : '+hex(id(self))) print(self.dummy) def modifyDummy(self, newValue): self.dummy = newValue class ContainerClass(): def __init__(self): self.attributeObject = attributeClass() self.dic = {'dynamicCall': self.attributeObject.printDummy } def resetAttribute(self): self.attributeObject = attributeClass() def main(): containerObject = ContainerClass() # 创建ContainerClass实例 print('--A--: 创建ContainerClass实例') containerObject.attributeObject.printDummy() # 直接调用printDummy containerObject.dic['dynamicCall']() # 动态调用printDummy print('--B--: 调用modifyDummy(5)') containerObject.attributeObject.modifyDummy(5) # 修改dummy值 containerObject.attributeObject.printDummy() # 直接调用 containerObject.dic['dynamicCall']() # 动态调用 print('--C--: 调用重置函数') containerObject.resetAttribute() # 重置容器的attributeClass属性 containerObject.attributeObject.printDummy() # 直接调用 containerObject.dic['dynamicCall']() # 动态调用 if __name__ == '__main__': main()
代码输出
--A--: 创建ContainerClass实例
id : 0x22ea3ad6ba0
0
id : 0x22ea3ad6ba0
0
--B--: 调用modifyDummy(5)
id : 0x22ea3ad6ba0
5
id : 0x22ea3ad6ba0
5
--C--: 调用重置函数
id : 0x22ea3d78b90
0
id : 0x22ea3ad6ba0
5
问题原因
字典中存储的self.attributeObject.printDummy是绑定方法,它在初始化时就已经和旧的attributeClass实例绑定,即使后续self.attributeObject指向新实例,字典里的绑定方法不会自动更新。
解决方法
方法1:重置属性时同步更新字典
在resetAttribute方法中同步更新字典条目,让其指向新实例的方法:
def resetAttribute(self): self.attributeObject = attributeClass() self.dic['dynamicCall'] = self.attributeObject.printDummy
方法2:存储未绑定方法并手动传入实例
字典中存储类的未绑定方法,调用时传入当前的attributeObject实例:
class ContainerClass(): def __init__(self): self.attributeObject = attributeClass() # 存储类的未绑定方法 self.dic = {'dynamicCall': attributeClass.printDummy } def resetAttribute(self): self.attributeObject = attributeClass() # 调用方式修改为传入当前实例 containerObject.dic['dynamicCall'](containerObject.attributeObject)
方法3:用Lambda包装动态获取逻辑
在字典中存储lambda函数,每次调用时动态获取最新的attributeObject实例:
class ContainerClass(): def __init__(self): self.attributeObject = attributeClass() self.dic = {'dynamicCall': lambda: self.attributeObject.printDummy() } def resetAttribute(self): self.attributeObject = attributeClass()
这种方式每次调用dic['dynamicCall']()时,都会自动获取最新的实例,无需手动更新字典。
内容的提问来源于stack exchange,提问作者coding_chicken
相关产品推荐
相关产品推荐

