当前位置: 首页 > news >正文

Python中的对象池与驻留机制:小整数、字符串与大整数

Python中的对象池与驻留机制:小整数、字符串与大整数

Python为优化内存使用和执行效率,设计了多种对象复用机制,其中最典型的是小整数对象池字符串驻留(intern)机制大整数对象池。以下是整理后的详细说明,包含规则、示例及修正补充:

一、小整数对象池

定义

Python对使用频率极高的小整数采用预创建对象池的策略,避免频繁创建和销毁相同整数对象,从而提升性能。

核心规则

  1. 范围固定:小整数对象池包含的整数范围是 [-5, 256]。这些整数在Python解释器启动时就被预先创建,且不会被垃圾回收机制回收。
  2. 全局复用:在程序的任何位置(无论LEGB作用域),只要使用该范围内的整数,引用的都是同一个对象。
  3. 与字符串的区别:单个字母的复用属于字符串驻留机制(见下文),而非小整数对象池的范畴,二者不可混淆。

示例

# 范围内的整数:复用同一对象
a = -5
b = -5
print(a is b)  # True(-5在[-5,256]范围内)a = 256
b = 256
print(a is b)  # True(256是范围上限)# 范围外的整数:每次创建新对象
a = 257
b = 257
print(a is b)  # False(257超出范围)a = -6
b = -6
print(a is b)  # False(-6超出范围)

注意事项

  • 小整数对象池是Python解释器的硬性规则,不受执行环境(终端、IDE)影响。
  • 范围外的整数(如257、-6)不享受池化,每次使用都会创建新对象。

二、字符串驻留(intern)机制

定义

字符串驻留是通过维护一个“字符串储蓄池”(字典结构),复用相同内容的字符串对象,从而节省内存的优化机制。

核心规则

1. 自动驻留的条件(Python 3.7+)

  • 内容符合“标识符规则”:仅包含字母(a-z, A-Z)、数字(0-9)、下划线(_)。
  • 编译期可确定:必须是字面量或字面量拼接(如'a'+'b'),编译时可确定结果。
  • 无长度限制:Python 3.7起移除了20字符的长度限制,只要符合标识符规则,无论长度如何都会自动驻留。
  • 空字符串:空字符串''始终被驻留(复用率极高)。

2. 不自动驻留的情况

  • 含特殊符号:字符串包含空格、标点等非标识符字符(如'hello world''a-b')。
  • 运行时动态生成:依赖变量、函数返回值等动态拼接的字符串(如a + 'b',其中a是变量)。

3. 手动驻留

对不符合自动驻留条件但需复用的字符串,可通过sys.intern(s)手动加入驻留池:

import syss1 = 'hello world'  # 含空格,不自动驻留
s2 = 'hello world'
print(s1 is s2)  # Falses1_interned = sys.intern(s1)
s2_interned = sys.intern(s2)
print(s1_interned is s2_interned)  # True(手动驻留后复用)

4. IDE特殊情况

PyCharm等IDE可能对短字符串(无论是否符合标识符规则)进行额外驻留优化(如'hello world'在IDE中可能被驻留),但这是环境特性,非Python原生规则。测试时建议使用命令行运行。

示例

# 符合标识符规则的字面量:自动驻留
s1 = "abc123"
s2 = "abc123"
print(s1 is s2)  # True# 字面量拼接(编译期确定):自动驻留
s3 = "ab" + "cd"  # 编译为"abcd"
s4 = "abcd"
print(s3 is s4)  # True# 含特殊符号:不自动驻留
s5 = "hello world"  # 含空格
s6 = "hello world"
print(s5 is s6)  # False(命令行环境)# 动态拼接(运行期生成):不自动驻留
s7 = "hell"
s8 = s7 + "o"  # 运行时拼接
s9 = "hello"
print(s8 is s9)  # False# 长度无限制(Python 3.7+)
s10 = "a" * 1000  # 长字符串,符合标识符规则
s11 = "a" * 1000
print(s10 is s11)  # True

注意事项

  • is用于判断是否为同一对象(比较内存地址),==用于比较值是否相等,实际开发中应优先使用==
  • 字符串不可变,拼接时推荐用join()(仅创建1个对象)而非+(多次创建对象)。

三、大整数对象池

定义

大整数指超出小整数范围([-5, 256])的整数。Python对大整数的复用机制与执行环境和代码块相关,无固定范围,仅在特定条件下复用对象。

核心规则

  1. 代码块内复用:在同一代码块中(如同一脚本、函数、类定义内),值相同的大整数会被复用为同一对象。
  2. 代码块间隔离:不同代码块(如不同函数、不同类)中的相同大整数会被视为不同对象。
  3. 执行环境差异
    • 终端(交互式环境):每次输入为一个独立代码块,因此相同大整数不会复用(每次创建新对象)。
    • IDE(如PyCharm):整个脚本作为一个代码块,同一代码块内的大整数会复用。

示例

1. 终端(交互式环境)

# 每次输入是独立代码块,大整数不复用
>>> a = 1000
>>> b = 1000
>>> a is b
False>>> c = -1888
>>> d = -1888
>>> c is d
False# 同一代码块内的大整数:复用
>>> def f():
...     a=1000
...     b=1000
...     print(a is b)
...
>>> f()
True
>>>

2. PyCharm(同一脚本,单代码块)

# 同一代码块内的大整数:复用
c1 = 1000
d1 = 1000
print(c1 is d1)  # True# 类定义属于独立代码块,类内变量为类代码块的一部分
class C1:c = 1000d = 1000  # 同一类代码块内,复用class C2:b = 1000  # 与C1属于不同代码块,不复用print(C1.c is C1.d)  # True(同一类代码块)
print(C1.c is C2.b)  # False(不同类代码块)

注意事项

  • 大整数对象池的行为完全依赖代码块划分,无固定范围,与小整数对象池的全局复用机制不同。
  • 开发中无需依赖大整数的复用特性,因环境差异可能导致结果不一致。

总结

机制 适用对象 核心规则 复用范围
小整数对象池 整数 范围固定为[-5, 256],解释器启动时预创建,全局复用 全程序(不受作用域/代码块影响)
字符串驻留机制 字符串 符合标识符规则的编译期字面量自动驻留,动态生成需手动驻留 驻留池内全局复用
大整数对象池 超出[-5,256]的整数 同一代码块内复用,不同代码块隔离,受执行环境影响 仅限同一代码块

三者的核心目的都是通过复用对象优化内存和性能,但适用场景和规则各有不同,开发中需注意其特性差异,避免依赖隐性规则导致bug。

http://www.hskmm.com/?act=detail&tid=25403

相关文章:

  • 基于ADMM无穷范数检测算法的MIMO通信系统信号检测MATLAB仿真,对比ML,MMSE,ZF以及LAMA
  • 点乘与叉乘的由来:从四元数到公理自洽的启示
  • 【算法深练】分组循环:“分”出条理,化繁为简 - 教程
  • java学习日记10.5
  • 【JNI】JNI基础语法
  • 【EF Core】通过 DbContext 选项扩展框架
  • 从Chrome渲染器代码执行到内核:MSG_OOB漏洞分析与利用
  • assistant-ui
  • 20251006 之所思 - 人生如梦
  • C# Avalonia 16- Animation- RotateButton
  • 2025 十一集训
  • 汇编实验3
  • 20251005 模拟测 总结
  • 基于Python+Vue开发的体育用品商城管理系统源码+运行步骤
  • 完整教程:Microsoft Word使用技巧分享(本科毕业论文版)
  • (转)The Ten Commandments of Digital Cotrol(Part1)
  • ctf逆向常见算法----base64
  • 02020409 EF Core基础09-一对一、多对多、EF Core基于关系的复杂查询
  • 02020503 EF Core高级03-分页查询、IQuerable底层的实现形式、DataReader、DataTable、EF Core中的异步方法
  • 02020502 EF Core高级02-IQuerable会延迟执行、分部和动态构建IQuerable、IQuerable的复用
  • 在 PyCharm 中,环境:bert_env , 执行 import wandb 报错。但是,在CMD窗口,环境:bert_env , 执行 import wandb 正常。
  • Linux_T(Sticky Bit)粘滞位详解 - 详解
  • P2831 [NOIP 2016 提高组] 愤怒的小鸟 题解
  • 库存中心(三层库存模型)
  • Valley靶机渗透实战:从凭证复用到Python库劫持
  • 10.05模拟赛反思
  • MariaDB收购SkySQL增强AI与无服务器能力
  • 单片机寄存器的四种主要类型! - 实践
  • TDengine 高级特性——读缓存
  • 非合作博弈之软性均衡:东方智慧与西方理论的融合框架