x=y=0
while True:
if x is y:
print(f"{x} is {y}")
else:
print(f"Attention! {x} not is {y}")
break
x+=1
y+=1
x=y=0
while True:
if x is y:
print(f"{x} is {y}")
else:
print(f"Attention! {x} not is {y}")
break
x-=1
y-=1
251 is 251
252 is 252
253 is 253
254 is 254
255 is 255
256 is 256
Attention! 257 not is 257
0 is 0
-1 is -1
-2 is -2
-3 is -3
-4 is -4
-5 is -5
Attention! -6 not is -6
这是一部分输出,我们可以看到当数据超过 256 和 - 5 的时候,它们不相等了,这是因为 python 解释器对性能的一些优化,把频繁使用的整数对象存储到了一个叫 small_ints 的对象池。数据范围是 [-5,256], 也就是说,只要在这个范围的数字,在任何引用的地方都不需要重新创建 int 对象,而是调用缓存池里面的对象,如果不在这个范围,那么即使这两个对象的数值相同,它们也是属于不同的对象。不过接下来让我们看一个更有趣的现象.
def main():
a = 257
b = 257
c = 257
print(b is c)
print(a is b)
print(a is c)
a += 1
b += 1
c += 1
print(b is c)
print(a is b)
print(a is c)
if __name__ == "__main__":
main()
True
True
True
False
False
False
程序打印的结果是这样,正常情况下 a,b,c 在一开始就应该是不同的对象,所以我们可以大胆猜测这属于 python 解释器的一些优化行为,在编译阶段就检测到多次复用 257, 所以给了它们一个相同的对象。而在执行到 + 1 的时候,数字是超过缓存池的范围的,所以又给每个数据单独的创建了一个新的对象。我们不妨把数字换成在缓存池的数据来验证一下.
def main():
a = 100
b = 100
c = 100
print(b is c)
print(a is b)
print(a is c)
a += 1
b += 1
c += 1
print(b is c)
print(a is b)
print(a is c)
if __name__ == "__main__":
main()
True
True
True
True
True
True
可以看到,只要在 [-5,256], 不管进行什么操作,只要数据是相同的,那么它们依然是同一个对象.
并且这种高频使用的数据使用缓存池储存起来来提高程序的性能,在 Java 里面也有类似的实现,我们下次再讲.
评论区