Python:is 和 == 的区别、小整数对象池 及 inte
2020-07-19 本文已影响0人
dex0423
1. 区别
- is,是 同一性操作符,比较的是对象的 id 是否相同,即对象的 内存地址 是否相同;
- ==,是 比较操作符,比较的是对象的 值 是否相等;
2. 示例
- 有如下代码和执行结果:
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> print("a 的 id: ", id(a))
>>> print("b 的 id:", id(b))
>>> print("is 比较结果 : ", a is b)
>>> print("== 比较结果 :", a == b)
a 的 id: 1811151687176
b 的 id: 1811151687368
is 比较结果 : False
== 比较结果 : True
- 这里我们发现,a 、b 的内存地址(id)是不同的,所以 is 比较结果为 false。而由于 a、b 两个 list 值相同,所以 == 比较结果为 true。
3. 注意
3.1. 小整数对象池
- 使用python命令行时对于小整数 [-5,256] 区间内的整数,python会创建小整数对象池,这些对象一旦创建,就不会回收,所有新创建的在这个范围的整数都是直接引用他即可,这就造成在 [-5,256] 区间内的整数不同变量只要值相同,引用地址也相同;
- 在 [-5,256] 区间范围外的整数同样遵循新建一个变量赋予一个地址。
- 示例:
>>> a = 1
>>> b = 1
>>> c = 257
>>> d = 257
>>> print("a 的 id: ", id(a))
a 的 id: 140712010608912
>>> print("b 的 id:", id(b))
b 的 id: 140712010608912
>>> print("c 的 id: ", id(c))
c 的 id: 2280561690800
>>> print("d 的 id:", id(d))
d 的 id: 2280561690672
>>> print("is 比较结果 : ", a is b)
is 比较结果 : True
>>> print("== 比较结果 :", a == b)
== 比较结果 : True
>>> print("is 比较结果 : ", c is d)
is 比较结果 : False # 注意:c 和 d 的内存地址(id)不同,所以此处比较结果为 false
>>> print("== 比较结果 :", c == d)
== 比较结果 : True
3.2. intern机制
- python中虽然字符串对象也是不可变对象,但python有个 intern 机制,简单来说就是维护一个字典,这个字典维护已经创建字符串(key)和它的字符串对象的地址(value),每次创建字符串对象都会和这个字典比较,没有就创建,重复了就用指针引用即可。相当于python对于字符串也是采用了对象池的原理(区别是intern机制中的字典是程序运行中创建并不断添加的,而小整数对象池是运行程序之前就创建好了的);
- 特别注意:如果字符串(含有空格),不可修改,没开启intern机制,不共用对象;
- 示例:
>>> a = "abc"
>>> b = "abc"
>>>
>>> c = "abc 123" # 注意: 字符串中间有空格
>>> d = "abc 123"
>>>
>>> print("a 的 id: ", id(a))
a 的 id: 2280562311088
>>> print("b 的 id:", id(b))
b 的 id: 2280562311088
>>>
>>> print("c 的 id: ", id(c))
c 的 id: 2280593916464
>>> print("d 的 id:", id(d))
d 的 id: 2280593916528
>>>
>>> print("is 比较结果 : ", a is b)
is 比较结果 : True
>>> print("== 比较结果 :", a == b)
== 比较结果 : True
>>>
>>> print("is 比较结果 : ", c is d)
is 比较结果 : False # 注意:c 和 d 的内存地址(id)不同,所以此处比较结果为 false
>>> print("== 比较结果 :", c == d)
== 比较结果 : True
4. 探讨
- 在实际测试过程中会发现,如果编译器不是用的 cmd 打开 python3,而是使用 pycharm,则 intern机制 出现了令人意外的结果,如果字符串(含有空格)其赋值对象的内存地址(id)确实相同的,is 比较结果为 true,这和命令行窗口执行的结果不同;
- 如下图:
![](https://img.haomeiwen.com/i14502986/506a1d9725b0036e.png)