meishaoming / blog

MIT License
1 stars 2 forks source link

python3 中的 is 和 == #99

Open meishaoming opened 4 years ago

meishaoming commented 4 years ago

对 is 和 == 的概念一直有些模糊,不太清楚什么时候该用哪个。

现在好像懂了。

is 是比较两个对象的 id() 结果是否相同,相当于比较两个变量(python中的变量都是指向某个对象的指针或引用)所引用的是否是同一个地址。

== 都说是「值比较」,其实 == 的默认行为等同于 is。但是对于许多对象我们期望 == 执行值比较,这就需要自行定制这些类型的比较行为,x==y 调用 x.__eq__(y)。比如内置的 str、int 等类型都有自己的 __eq__() 方法。

对于单例对象(整个 python3 环境里只有一个实例),我们总是使用 is 或 is not 来判断。比如 if a is not None。None 和 NotImplemented 都是单例对象。

x is y 意味着 x == y ,这很显然,指向同一个对象的两个变量的值也肯定是相同的。

但 x==y 并不意味着 x is y,比如两个字符串对象的内容相同,但它们是两个独立的对象,在内存中的地址不同,is 肯定是 False。

以下引用内容来自 《python语言参考》

6.10.1. 值比较
...

默认的一致性比较 (== 和 !=) 是基于对象的标识号。 因此,具有相同标识号的实例一致性比较结果为相
等,具有不同标识号的实例一致性比较结果为不等。 规定这种默认行为的动机是希望所有对象都应该是
自反射的 (即 x is y 就意味着 x == y)。

...

按照默认的一致性比较行为,具有不同标识号的实例总是不相等,这可能不适合某些对象值需要有合理
定义并有基于值的一致性的类型。 这样的类型需要定制自己的比较行为,实际上,许多内置类型都是这
样做的。