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

求助:类实例内存地址相关代码行为不符合预期,求解析

嘿,我完全懂你的困惑——按常理来说,同一个类的两个独立实例确实该占据不同的内存地址,行为上也应该是各自独立的。不过既然你的代码执行成功了,大概率是某个容易忽略的细节在起作用,咱们一步步拆解可能的原因:

1. 你其实没创建两个独立实例,只是复制了引用

很多时候我们会不小心把同一个实例的引用赋值给另一个变量,看起来像是两个实例,实则指向内存里同一个对象。比如:

class MyClass:
    pass

obj1 = MyClass()
obj2 = obj1  # 这里只是把obj1的引用给了obj2,不是新建实例

这种情况下,obj1和obj2的内存地址完全一致,用id(obj1) == id(obj2)就能快速验证。

2. 类里用了类变量而非实例变量

如果你的类把变量定义在类层级(而非__init__方法里),那这个变量是所有实例共享的。比如:

class MyClass:
    shared_data = []  # 这是类变量,所有实例共用

obj1 = MyClass()
obj2 = MyClass()
obj1.shared_data.append("hello")
print(obj2.shared_data)  # 会输出["hello"],因为是共享的

这种时候哪怕实例地址不同,操作类变量也会互相影响,容易让你误以为是同一个实例在起作用。解决办法是把变量移到__init__里,变成每个实例独有的实例变量:

class MyClass:
    def __init__(self):
        self.instance_data = []  # 每个实例独立拥有的变量

3. 自定义了比较/运算符重载方法

如果你的类重写了__eq__这类方法,可能会让两个不同实例在比较时返回True,看起来像是“同一个实例”。比如:

class MyClass:
    def __init__(self, value):
        self.value = value
    def __eq__(self, other):
        return self.value == other.value  # 只比较value,不管内存地址

obj1 = MyClass(10)
obj2 = MyClass(10)
print(obj1 == obj2)  # 输出True,但id(obj1) != id(obj2)

这种情况下实例本身是独立的,但自定义的比较逻辑让它们“看起来相等”,可能会误导你的判断。

4. 类实现了对象复用逻辑

如果你的类重写了__new__方法做了对象池或者单例逻辑,那创建的实例可能会被复用。比如:

class MyClass:
    _pool = {}
    def __new__(cls, key):
        if key not in cls._pool:
            cls._pool[key] = super().__new__(cls)
        return cls._pool[key]

obj1 = MyClass("demo")
obj2 = MyClass("demo")
# 这两个实例是同一个,因为__new__返回了缓存的对象

给你的排查建议

  • 先打印两个实例的id()值,确认它们是不是真的不同实例;
  • 检查类中的变量定义,区分开类变量和实例变量;
  • 查看类中是否有自定义的__eq__/__new__这类特殊方法;
  • 如果涉及到实例间的操作,逐步打印关键变量的值,追踪数据的变化来源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:48:12