首页 新闻 会员 周边 捐助

Python的对象缓存

0
[已关闭问题] 关闭于 2025-11-25 14:37

只对不可变对象进行缓存

  • 可变对象(列表、字典、集合)永远不会缓存
  • l1 = [1, 2, 3]
    l2 = [1, 2, 3]
    print(l1 is l2)  # 总是False

     

Python的对象缓存包括:

  • 小整数缓存(-5~256)
  • 字符串interning(短字符串、标识符)
  • 空不可变容器(空元组、空frozenset)
  • 单例对象(None、True、False)
  1. 不同Python实现行为不同

    • CPython: 有上述缓存机制
    • PyPy: 可能有更积极的优化
    • Jython/IronPython: 基于JVM/.NET,行为不同
    • MicroPython: 为了节省内存,缓存范围可能不同

 

小整数缓存(-5 ~ 256)

CPython在启动时预先创建了范围在-5到256之间的整数对象池

# 小整数缓存示例
a = 100
b = 100
print(a is b)  # True - 指向同一个对象

c = 257
d = 257
print(c is d)  # 在交互式环境通常为False,在脚本中可能为True,取决于编译优化

字符串Interning

Python会对某些字符串进行"interning"(字符串驻留),确保相同内容的字符串只存储一份:

# 字符串字面量通常会被intern
s1 = "python"
s2 = "python"
print(s1 is s2)  # True - 相同字面量通常指向同一对象

# 动态创建的字符串不会自动intern
s3 = "py" + "thon"  
s4 = "".join(["p", "y", "t", "h", "o", "n"])
print(s1 is s3)  # 可能为True(编译优化)
print(s1 is s4)  # False - 运行时创建的字符串

# 手动intern字符串
import sys
s5 = sys.intern("hello world!")
s6 = sys.intern("hello world!")
print(s5 is s6)  # True - 手动intern后指向同一对象

空元组

t1 = ()
t2 = ()
print(t1 is t2)  # True - 只有一个空元组实例

布尔值

print(True is True)  # True - 单例
print(False is False)  # True - 单例
b1 = bool(1)
b2 = bool(1)
print(b1 is b2)  # True - 指向相同的True对象

None

print(None is None)  # True - 经典的单例模式

小浮点数

f1 = 0.0
f2 = 0.0
print(f1 is f2)  # 通常为True,但不应依赖

空frozenset

fs1 = frozenset()
fs2 = frozenset()
print(fs1 is fs2)  # True - 只有一个空frozenset实例

代码块优化

在同一个代码块(如函数、模块级别)中,CPython会进一步优化:

def example():
    x = 1000
    y = 1000
    print(x is y)  # True - 同一代码块内的常量优化

example()

# 但不同代码块之间:
def func1():
    return 1000

def func2():
    return 1000

print(func1() is func2())  # False - 不同代码块
*Tesla*的主页 *Tesla* | 小虾三级 | 园豆:1152
提问于:2025-11-25 14:37
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册