侧边栏壁纸
博主头像
马杰如的博客

一切有为法,如梦幻泡影,如露亦如电,应作如是观。

  • 累计撰写 5 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Python语言里的一些细节 ------- 整数比较

马杰如
2025-05-27 / 0 评论 / 2 点赞 / 13 阅读 / 0 字
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 里面也有类似的实现,我们下次再讲.

2

评论区