核心一句话
不存在官方叫"大整数池"的东西 ,你看到的"大整数池"只是网上教学通俗叫法,不是 CPython 正式概念;只有小整数池是固定预创建、保证复用 ,大整数的复用只是编译器常量折叠优化,不稳定,不能依赖。
1. 两个东西本质区别
✅ 小整数池(CPython 原生固定缓存)
- 范围:
[-5, 256],解释器启动就提前建好 - 保证:任何地方,只要是这个区间数字,一定是同一个对象 ,
is判断一定成立 - 不受环境影响:REPL / py脚本 结果一致
- 目的:高频小数字,避免反复分配内存
⚠️ 所谓"大整数池"(民间叫法,不是真实缓存池)
不是提前建好的池子,初始是空,创建一个存一个 ,这个说法不准确,它是常量折叠(constant folding)
- 原理:Python 在编译阶段 扫描代码,如果同一段代码里出现字面量
257、1000,编译器会直接合并成同一个常量对象,省内存。 - 局限:只作用于同一段代码块,不是全局永久缓存。
- 不是持久池:不会像小整数那样常驻。离开这个代码上下文,对象该GC就GC。
2. 为什么 REPL 和脚本里面 257 is 257 结果不一样?
- 脚本文件(.py)
整段代码一次性编译,编译器看到两处字面量257,合并成同一个常量 →257 is 257→True - 交互式REPL(一行一行输入)
每一行是独立代码块,每行单独编译。第一行257是一个对象,下一行再写257,重新创建新对象 →257 is 257→False
python
# REPL逐行输入:
>>> a = 257
>>> b = 257
>>> a is b
False
# 全部写在一个py文件一次性运行
a = 257
b = 257
print(a is b) # True
3. 重点:这句话的特别含义(面试考点)
有时连续赋值的相同大整数也可能指向同一对象,这是因为Python环境的优化机制,但是这个优化不是绝对的,也取决于解释器以及交互式以及脚本环境。
含义拆解:
-
不要用
is判断大整数是否相等!is判断对象身份(id) ;==判断数值 。哪怕两个大整数值一样,
is有可能True也有可能False,行为不可预测,不能写业务代码依赖这个特性 。✅ 永远用
==判断数字相等❌ 禁止
if num is 1000这种写法 -
优化不是CPython内置全局缓存,只是编译期的临时优化,其他Python实现(Jython/IronPython)甚至没有这个优化,代码会跨解释器出bug。
-
小整数是语言实现固定保证 ;大整数只是可选编译器优化,二者性质完全不同。
4. 补充误区纠正
网上说"大整数池,创建一个存一个",容易让人误以为:
只要创建过大整数,后面任何地方都复用这个对象(像小整数池一样全局缓存)
❌ 错误。
大整数不会全局缓存。只要脱离代码块,引用消失就会被垃圾回收。下一次新建,又是新对象。
快速总结记忆版
- 小整数池:预创建、全局保证复用,稳定可靠(CPython -5~256)
- 大整数复用:编译常量折叠,仅同代码块生效,REPL/脚本行为不同,属于偶然优化,不可依赖
- 编码原则:判断数值相等只用 ==,不要用 is