You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重置属性后动态调用属性方法指向错误实例的问题解决

动态调用指向实例的问题

我定义了一个作为其他类属性的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 05:25:56