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

Python 2.7中自定义类为何默认出现记忆化(缓存)行为?

问题根源:可变对象的引用传递,而非Python自动缓存实例

首先明确:Python 不会自动缓存类的实例,你遇到的现象完全是因为字典是可变对象,且两个实例共享了同一个字典引用。

具体分析两种场景:

  1. 第一种场景(出现"缓存"错觉)
    你创建的test_dict是一个字典对象,两次实例化MyClient时都传入了这个同一个对象:

    test_dict = {"foo": "bar"}
    x = MyClient(test_dict).run()
    y = MyClient(test_dict).run()
    

    MyClient的__init__里只是把self.value指向传入的字典,并没有创建新字典。所以两个实例的self.value其实是同一个字典对象的引用。当run方法修改self.value时,本质是修改了这个共享的字典,自然另一个实例的self.value也会看到变化——这不是实例被缓存,是字典本身被共享了。

  2. 第二种场景(无"缓存"现象)

    test_dict = {"foo": "bar"}
    x = MyClient(test_dict)
    y = MyClient({"foo": "bar"})
    

    这里y的实例化传入的是新创建的字典对象({"foo": "bar"}会生成一个全新的字典,内存地址和test_dict不同),所以x.value和y.value指向两个独立的字典,修改其中一个不会影响另一个。

额外的代码错误

你的run方法定义有问题:

def run():
    # do some stuff and update self.value

在Python 2.7中,实例方法必须把self作为第一个参数,否则调用时会抛出TypeError: run() takes no arguments (1 given)。你实际运行的代码应该是修正后的:

def run(self):
    # do some stuff and update self.value

验证方法

可以打印对象的内存地址确认:

test_dict = {"foo": "bar"}
x_inst = MyClient(test_dict)
y_inst = MyClient(test_dict)
print(id(x_inst.value))  # 和下面的输出相同
print(id(y_inst.value))

z_inst = MyClient({"foo": "bar"})
print(id(z_inst.value))  # 和上面的输出不同

解决办法

如果希望每个MyClient实例拥有独立的字典副本,在__init__里复制传入的字典:

class MyClient(object):
    def __init__(self, my_dict):
        self.value = dict(my_dict)  # 创建字典副本
        # 或者 self.value = my_dict.copy()

    def run(self):
        # 修改self.value只会影响当前实例的副本
        self.value["new_key"] = "new_value"

内容的提问来源于stack exchange,提问作者Klutch27

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:52:55