Python的is和==的区别

首先来看几个例子:

(1)
>>> a = 'hello'
>>> b = 'hello'
>>> print(id(a),id(b))
2037326236784 2037326236784
>>> print(a is b)
True
>>> print(a == b)
True

(2)
>>> a = 'hello world'
>>> b = 'hello world'
>>> print(id(a),id(b))
2037326180976 2037326180784
>>> print(a is b)
False
>>> print(a == b)
True

(3)
>>> a = 'hello world'
>>> b = a
>>> print(id(a),id(b))
2037326181168 2037326181168
>>> print(a == b)
True
>>> print(a is b)
True

上述例子(2)中的a、b分别指向的是不同的内存空间,此时a is b返回False,a == b返回True。但例(3)中当a和b指向相同内存空间时a is b返回的是True,a == b返回仍是True。没错,根据官方文档中的说法,is表示的是对象标识符(object identity),而==用来检查值相等(equality)。换句话说,is就是用来判断两个对象是否在本质上是一个对象,即占用的是否是相同的内存空间。所以当我们在判断a is b时其实是判断id(a) == id(b),而检查a == b时其实是调用了__eq__()方法,相当于a.eq(b)。

不过有朋友纳闷(1)和(2)又是怎么回事?其实这里的Python字符串的intern机制,该机制规定:当两个或以上的字符串变量它们的值相同且仅由数字字母下划线构成,或者值仅含有一个字符时,内存空间中只创建一个对象来让这些变量都指向该内存地址。当字符串不满足该条件时,相同值的字符串变量在创建时都会申请一个新的内存地址来保存值。

扩展一个内存管理机制方面小知识点:

>>> id([1,2,3]) == id([4,5,6])
True
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> print(id(a), id(b))
2037326252488 2037326229256

有很多人弄不明白为什么id([1,2,3]) == id([4,5,6]),这是因为Python会实时销毁没有引用计数的对象。一旦在内存中创建了一个对象但是没有为其添加引用计数,该段代码执行完后就会回收地址,在这个例子中计算完[1,2,3]的id后list被销毁,计算右边的id时list实时创建,复用了左边list用过的内存。但是生成的时间有先后,他们并不代表同一个对象。

猜你喜欢

转载自my.oschina.net/u/3723649/blog/1814901