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

Python中is not比较行为疑问:同名属性为何ID不同?

关于防御性复制中属性身份比较与ID变化的问题解答

为什么a.lst_different_name is not a.lst_different_name返回True?

核心原因是这个属性的访问器(getter)每次调用都会返回一个全新的对象副本——这正是防御性复制的设计目的:防止外部代码直接修改类内部的可变对象(比如列表)。

is运算符比较的是两个对象的内存身份(即ID),而非值是否相等。如果你的类定义类似下面这样:

class SomeClass:
    def __init__(self):
        self._internal_list = [1, 2, 3]
    
    @property
    def lst_different_name(self):
        # 每次访问都返回内部列表的新副本
        return self._internal_list.copy()

那么每次调用a.lst_different_name时,都会执行copy()生成一个新列表。两次调用得到的是两个完全独立的对象,内存地址自然不同,因此a.lst_different_name is a.lst_different_name会返回False,对应的is not就是True。

为什么同一属性的ID会有时相同有时不同?

这和Python的垃圾回收机制以及内存复用规则有关:

  • 当你调用id(a.lst_different_name)时,生成的临时列表对象没有被任何变量持有引用,Python的垃圾回收器会快速回收这块内存空间。
  • 下一次调用id(a.lst_different_name)时,新生成的列表对象可能会复用之前被回收的内存地址,此时两次ID就会相同。
  • 如果在两次调用之间有其他操作创建了新对象、占用了那块内存,新生成的列表就会使用新的内存地址,ID也就随之不同。

直观示例:

a = SomeClass()
# 第一次调用,生成临时列表,ID为X
print(id(a.lst_different_name))  
# 临时列表已被回收,新列表复用X地址
print(id(a.lst_different_name))  
# 创建新对象占用内存
temp = [4, 5, 6]
# 新列表只能使用新地址,ID变为Y
print(id(a.lst_different_name))  

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:15:36