news 2026/2/26 15:03:54

类变量和实例变量的内存分配有什么不同?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
类变量和实例变量的内存分配有什么不同?

你想了解 Python 类变量和实例变量在内存分配上的本质差异,核心体现在分配时机、存储位置、内存份数、生命周期四个关键维度,下面结合原理说明和代码验证,详细拆解两者的不同:

一、核心内存分配差异对比

内存分配维度类变量实例变量
分配时机加载 / 定义时(程序运行到类定义代码时)实例创建时(调用类构造器类名()时)
存储位置类对象的命名空间(类的内存区域)实例对象的独立命名空间(每个实例的内存区域)
内存份数仅分配1 份内存,全局唯一每个实例分配独立 1 份内存,实例数量 = 内存份数
生命周期随类的销毁而销毁(程序结束 / 类被删除)随实例的销毁而销毁(实例被垃圾回收时)
访问映射实例访问类变量时,是「查找类的命名空间」,而非实例自身存储实例访问自身变量时,直接查找自身命名空间

二、逐维度详细解释 + 代码验证

1. 分配时机:类加载时分配类变量,实例创建时分配实例变量
  • 类变量:程序运行到class 类名:代码块时,Python 会创建类对象并为类变量分配内存,无需创建实例即可存在。
  • 实例变量:只有当调用类名()创建实例时,Python 才会为该实例分配内存,并在__init__方法中初始化实例变量,类加载阶段不存在实例变量。

python

运行

# 验证:类加载时,类变量已存在,实例变量尚未分配 class Student: # 类加载时,class_var 已分配内存 class_var = "类变量内存已分配" def __init__(self, name): # 只有创建实例时,name 才会被分配内存 self.name = name # 无需创建实例,可直接访问类变量(证明类变量已分配内存) print(Student.class_var) # 输出:类变量内存已分配 # 此时无实例,实例变量不存在(无法访问) # print(Student.name) # 报错:AttributeError,实例变量未分配 # 创建实例后,实例变量才分配内存 stu1 = Student("张三") print(stu1.name) # 输出:张三(实例变量内存已分配)
2. 存储位置:类变量存在类命名空间,实例变量存在实例命名空间

Python 中,类和实例都有专属的__dict__属性(字典结构),用于存储自身的属性(变量),通过打印__dict__可直观看到两者的存储位置差异:

  • 类变量:存储在类名.__dict__中,属于类的命名空间。
  • 实例变量:存储在实例名.__dict__中,属于实例的独立命名空间,实例的__dict__中不会存储类变量(仅在访问时回溯到类的命名空间)。

python

运行

class Student: class_var = "北京大学" # 类变量:存在类的 __dict__ def __init__(self, name, score): self.name = name # 实例变量:存在实例的 __dict__ self.score = score # 实例变量:存在实例的 __dict__ # 查看类的命名空间:包含类变量 print("类的命名空间:", Student.__dict__) # 输出(关键部分):{'class_var': '北京大学', ...} # 创建两个实例 stu1 = Student("张三", 90) stu2 = Student("李四", 85) # 查看实例1的命名空间:仅包含自身的实例变量,无类变量 print("stu1 的命名空间:", stu1.__dict__) # 输出:{'name': '张三', 'score': 90} # 查看实例2的命名空间:独立于stu1,仅包含自身实例变量 print("stu2 的命名空间:", stu2.__dict__) # 输出:{'name': '李四', 'score': 85} # 实例访问类变量时,是回溯到类的命名空间查找,而非自身存储 print(stu1.class_var) # 本质是查找 Student.__dict__['class_var']
3. 内存份数:类变量仅 1 份内存,实例变量多份独立内存
  • 类变量:全局只有 1 份内存地址,所有实例共享这一份数据,修改类变量(通过类名)会影响所有实例。
  • 实例变量:每个实例对应独立的内存地址,实例之间的变量互不干扰,修改一个实例的变量不会影响其他实例。

python

运行

class Student: class_var = 0 # 仅1份内存 def __init__(self, name): self.name = name # 每个实例独立内存 # 验证类变量的内存地址(所有引用指向同一内存) stu1 = Student("张三") stu2 = Student("李四") # 类、stu1、stu2 访问的 class_var 是同一内存地址 print(id(Student.class_var)) # 输出:xxx(唯一内存地址) print(id(stu1.class_var)) # 输出:xxx(与上面地址相同) print(id(stu2.class_var)) # 输出:xxx(与上面地址相同) # 验证实例变量的内存地址(每个实例独立) print(id(stu1.name)) # 输出:yyy(独立内存地址) print(id(stu2.name)) # 输出:zzz(与上面地址不同) # 修改类变量(1份内存),所有实例同步变化 Student.class_var = 100 print(stu1.class_var, stu2.class_var) # 输出:100 100 # 修改实例变量(独立内存),互不影响 stu1.name = "张小三" print(stu1.name, stu2.name) # 输出:张小三 李四
4. 生命周期:类变量随类销毁,实例变量随实例销毁
  • 类变量:类在程序运行期间始终存在,只有当程序结束(或通过del显式删除类)时,类对象被销毁,类变量的内存才会被回收。
  • 实例变量:实例被创建后存在,当实例不再被引用(如变量赋值为None、超出作用域),Python 垃圾回收机制会销毁该实例,实例变量的内存也会随之被回收。

python

运行

class Student: class_var = "生命周期随类" def __init__(self, name): self.name = name # 生命周期随实例 # 1. 类变量始终存在(程序运行中) print(Student.class_var) # 正常访问 # 2. 创建实例,实例变量分配内存 stu = Student("张三") print(stu.name) # 正常访问 # 3. 销毁实例(解除引用,触发垃圾回收) stu = None # 实例无引用,会被垃圾回收,实例变量内存释放 # print(stu.name) # 报错:NameError(实例已销毁) # 4. 类变量仍存在(类未销毁) print(Student.class_var) # 仍能正常输出:生命周期随类 # 5. 显式删除类,类变量内存释放 del Student # print(Student.class_var) # 报错:NameError(类已销毁,类变量不存在)

三、特殊场景:可变类型类变量的内存特性(补充)

对于列表、字典等可变类型类变量,其「内存地址(引用)」仅 1 份(符合类变量内存特性),但实例可以修改其内部元素(无需重新赋值),本质是操作同一份内存中的可变对象,因此会影响所有实例:

python

运行

class Group: # 可变类型类变量:仅1份内存(存储列表的引用) members = [] def add_member(self, name): # 操作同一份内存中的列表元素,所有实例共享变化 self.members.append(name) g1 = Group() g2 = Group() g1.add_member("张三") # 两者访问的是同一份内存中的列表 print(g1.members) # 输出:['张三'] print(g2.members) # 输出:['张三'] print(id(g1.members) == id(g2.members)) # 输出:True(同一内存地址)

四、总结

  1. 类变量:类加载时分配 1 份内存,存在类命名空间,生命周期随类,所有实例共享同一份内存数据;
  2. 实例变量:实例创建时分配独立内存,存在各自实例命名空间,生命周期随实例,实例间内存互不干扰;
  3. 实例访问类变量是「回溯查找类命名空间」,并非实例自身存储了类变量;
  4. 可变类型类变量的「引用内存」仅 1 份,修改内部元素会影响所有实例,本质是操作同一可变对象。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/15 20:29:01

为什么你的Open-AutoGLM跑不动?手机端部署必须掌握的6项核心技术

第一章:Open-AutoGLM手机端部署概述Open-AutoGLM 是基于 AutoGLM 架构优化的轻量化大语言模型,专为移动端设备设计,支持在资源受限的环境中高效运行自然语言任务。其核心优势在于通过模型压缩、算子融合与硬件加速技术,在保持较高…

作者头像 李华
网站建设 2026/2/22 11:34:38

IDM长期使用完整指南:从问题诊断到系统级解决方案

Internet Download Manager作为业界领先的下载加速工具,其使用体验往往成为用户关注的焦点。本文将深入解析IDM使用机制的技术原理,并提供从基础诊断到高级配置的完整解决方案。 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Rese…

作者头像 李华
网站建设 2026/2/25 15:37:26

ArduPilot传感器集成实战:从零构建高性能IMU驱动

ArduPilot传感器集成实战:从零构建高性能IMU驱动 【免费下载链接】ardupilot 项目地址: https://gitcode.com/gh_mirrors/ard/ardupilot 引言:为什么你的传感器总是不工作? "传感器连接正常,但数据就是读不出来&quo…

作者头像 李华
网站建设 2026/2/16 2:17:11

Test-Agent终极指南:5步搭建AI智能测试平台

Test-Agent终极指南:5步搭建AI智能测试平台 【免费下载链接】Test-Agent 项目地址: https://gitcode.com/gh_mirrors/te/Test-Agent 在当前软件测试领域,AI智能测试平台正在革命性地改变传统测试方式。Test-Agent作为一款开源的AI测试助手&#…

作者头像 李华
网站建设 2026/2/26 21:42:36

揭秘Open-AutoGLM插件:如何在3步内实现大模型推理自动化?

第一章:揭秘Open-AutoGLM插件的核心价值Open-AutoGLM 是一款专为大语言模型(LLM)任务自动化设计的开源插件,其核心目标是通过结构化指令解析与上下文感知调度机制,提升模型在复杂业务场景中的执行效率与准确性。该插件…

作者头像 李华