Python中同ID对象is判断为False、==判断为True的原因咨询
搞懂Python中
is和==的区别,解决你的困惑 嘿,刚从C#转Python确实会遇到这种和直觉不一样的坑,我来给你把这个问题讲明白~
首先得把两个运算符的本质掰扯清楚,这和C#里的逻辑正好反过来,很容易搞混:
1. is vs == 的核心差异
is是身份判断:它检查的是两个变量是否指向内存中的同一个对象实例,底层比的是对象的内存地址(也就是Python内置id()函数返回的值)。这就像C#里的object.ReferenceEquals(a, b)。==是值相等判断:它调用对象的__eq__()方法,判断两个对象的「内容/业务逻辑」是否相等。这类似C#里重载后的==运算符,默认情况下对于自定义类,Python的==和is行为一致,但很多框架或自定义类会重写__eq__,比如用对象的业务ID来判断相等。
2. 为什么你会遇到这种情况?
你提到的「ID均为4」应该是对象自身的业务属性(比如event.source.id = 4),而不是Python的id()返回的内存地址。如果是后者,is绝对会返回True——因为同一个内存地址必然是同一个对象。
出现==为True但is为False的情况,本质是:
event.source和self.component是两个不同的对象实例,但它们的业务属性(比如ID)完全相同,而且类的__eq__方法被定义为比较这些业务属性,所以==返回True。- 至于你补充的「初始化时component和self.component的Python ID为0x18,但事件处理时同ID的两者is仍为False」,大概率是框架在事件触发时,返回的
event.source是一个新创建的对象实例(或者是代理/包装后的对象)。比如很多UI框架会在事件传递时,从组件树中重新获取实例,或者序列化反序列化对象,导致看起来内容一样,但内存地址已经变了。
3. 解决办法
- 如果你需要的就是「内容/业务逻辑相等」,那直接用
==就好,这完全符合你的需求,不用纠结is的结果。 - 如果你确实要判断是不是同一个内存实例,可以打印两者的Python内置
id()确认:
如果这两个值不一样,那就是不同实例,print(id(event.source), id(self.component))is返回False是正常的。 - 如果是框架导致的实例重复问题,你可以给组件对象添加一个唯一的实例标识(比如用
uuid生成),比如:
之后通过比较import uuid class YourComponent: def __init__(self): self.instance_id = uuid.uuid4()instance_id来判断是不是同一个逻辑实例。
内容的提问来源于stack exchange,提问作者Claus Nielsen
相关产品推荐
相关产品推荐

