小整数池是cpython的性能优化机制,范围固定为-5到256,仅对编译期确定的字面量生效;超出范围或动态创建的整数不共享对象,is比较不可靠,应始终用==比较数值。

因为CPython解释器启动时就预分配并复用这些整数对象,避免频繁内存分配和GC开销,本质是性能优化手段,不是语言规范。
小整数池的范围和触发条件
范围固定为 -5 到 256(含),这是 CPython 源码硬编码的值,其他解释器(如 PyPy)可能不同。这个机制只对字面量或编译期可确定的整数生效:
-
a = 100、b = 256→ 复用同一对象,a is b为True -
a = 255 + 1→ 即使结果是256,也不保证命中池(取决于编译优化级别) -
a = int("256")或a = eval("256")→ 动态创建,不进池,is比较大概率False
为什么选-5到256而不是其他范围?
这个区间覆盖了绝大多数计数、索引、状态码等高频使用场景(比如循环变量、range(100)、HTTP状态码 200 / 404),同时控制内存占用在合理范围内。实测表明:
-
id(-5)和id(256)返回稳定地址,且在同进程内多次调用结果一致 -
id(257)每次可能不同,尤其在交互式环境反复赋值后明显 - 超出范围的整数对象生命周期受 GC 管理,而池内对象永不回收
误用 is 比较整数的典型错误
开发者常把 is 当作“更高效”的 ==,但这是危险的:
-
if code is 200:→ 在脚本中可能偶然成立,但在模块导入、函数参数传递、动态计算等场景下极易失效 -
is的行为依赖对象身份,而整数对象身份只在池内有保障;==始终比较值,语义清晰、行为稳定 - IDE(如 PyCharm)可能因底层优化让
257 is 257返回True,但这不可移植、不可预测,绝不能依赖
真正需要对象身份判断的场合极少,基本只限于 None、True、False 这类单例。对普通数值,== 是唯一安全选择——小整数池的存在,是为了让解释器跑得更快,不是为了让你写 is。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











