You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.13中类实例__dict__内存占用差异原因咨询

关于Python 3.13中实例__dict__内存占用差异的疑问

以下代码在Python 3.13中运行:

import sys


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y


v1 = Vector(1, 2)
v2 = Vector(1, 2)
print(f"v1 __dict__ : {sys.getsizeof(v1.__dict__)} bytes")
print(f"v2 __dict__ : {sys.getsizeof(v2.__dict__)} bytes")

v3 = Vector(1, 2)
v4 = Vector(1, 2)
print(f"v3 __dict__ : {sys.getsizeof(v3.__dict__)} bytes")
print(f"v4 __dict__ : {sys.getsizeof(v4.__dict__)} bytes")

v5 = Vector(1, 2)
print(f"v5 __dict__ : {sys.getsizeof(v5.__dict__)} bytes")

v6 = Vector(1, 2)
print(f"v6 __dict__ : {sys.getsizeof(v6.__dict__)} bytes")

输出结果:

v1 __dict__ : 288 bytes
v2 __dict__ : 288 bytes
v3 __dict__ : 272 bytes
v4 __dict__ : 272 bytes
v5 __dict__ : 264 bytes
v6 __dict__ : 256 bytes

疑问点:

  • 为何不同Vector实例的__dict__内存占用不同?
  • 调整print语句位置会改变结果的原因是什么?
  • v2与v3的内存占用为何存在差异?
  • 该代码在不同Python版本中表现不同的原因?

解答

1. 不同实例__dict__内存占用不同的原因

Python的__dict__是存储实例属性的字典对象,Python 3.13对小字典的内存分配做了精细优化。当重复创建结构完全相同的实例时,解释器会识别出__dict__的键模式(这里固定是x和y两个键),后续实例的__dict__会复用已识别的结构信息,采用更紧凑的内存布局,避免默认字典的冗余预留空间,因此内存占用逐步降低。

2. 调整print语句位置会改变结果的原因

核心在于实例创建顺序与解释器的优化时机。如果先批量创建所有实例再统一打印,解释器会在创建过程中完成对实例__dict__结构的识别,所有实例的__dict__会直接使用优化后的内存布局,内存占用会趋于一致。而原代码中穿插的print语句,相当于打断了连续的实例创建流程,前两个实例创建后立即打印时,解释器还未完成结构优化,后续实例则在优化生效后创建,因此出现差异。

3. v2与v3内存占用存在差异的原因

v2属于前两个创建的实例,此时解释器还处于“学习”该类实例__dict__结构的阶段,它的__dict__使用的是字典默认的内存分配逻辑(预留了额外空间);而v3是在v1、v2创建并打印之后生成的,此时解释器已经确定该类实例的__dict__只会包含固定的两个键,因此为v3分配了更紧凑的内存空间,不再保留冗余预留,所以内存占用更低。

4. 不同Python版本表现不同的原因

Python的字典实现一直在迭代优化:

  • 3.7之前字典无序,3.7+改为有序;
  • 3.10引入紧凑字典优化,压缩小字典的内存占用;
  • 3.13进一步针对同结构实例的__dict__做了动态优化,根据创建顺序调整内存分配策略。

不同版本的内存管理逻辑、字典优化程度不同,导致相同代码的输出结果不一致。比如在Python 3.10及更早版本中,可能所有实例的__dict__内存占用都相同,因为当时的优化还未覆盖动态调整的场景。


内容的提问来源于stack exchange,提问作者Johnson Francesca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:45:03