news 2026/6/10 18:14:38

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

作者头像

张小明

前端开发工程师

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/6/9 23:39:52

BiliPlus:6大功能让你的B站体验焕然一新!免费开源插件深度体验

还在为B站首页的杂乱推荐和干扰性热搜烦恼吗?BiliPlus这款专业的B站增强插件,通过六大核心功能的深度优化,为你打造一个纯净、高效、个性化的B站环境。作为完全免费的开源项目,它像一位贴心的数字助手,默默提升你的每一…

作者头像 李华
网站建设 2026/6/10 15:03:37

Transformer架构详解:大模型开发者的必学之路(收藏必备)

Transformer凭借其结构优雅性与卓越性能,已成为自然语言处理等领域中具有里程碑意义的模型。本节将深入解析Transformer架构的设计精妙之处,系统阐述其工作机制,帮助读者理解该模型如何高效处理信息并捕捉数据中复杂的依赖关系。 该模型由谷歌…

作者头像 李华
网站建设 2026/6/10 3:07:02

收藏!AI Agent入门到精通:让AI真正替你干活的终极指南

过去两年,人工智能的风口接连不断: 从 ChatGPT 到 AI 绘画,从“AI 写文案神器”到“AI 写代码助手”。 但如果你留意科技圈的动向,会发现一个新热词正被频繁提起——AI Agent(智能体)。很多人可能还没完全弄…

作者头像 李华
网站建设 2026/6/10 6:45:41

【Java毕设源码分享】基于springboot+vue的教育资源共享平台的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/6/10 11:54:59

揭秘Open-AutoGLM底层架构:如何高效训练专属AI Agent?

第一章:Open-AutoGLM模型概述Open-AutoGLM 是一个开源的自动推理语言模型框架,专为增强大语言模型在复杂任务中的规划与执行能力而设计。该模型结合了思维链(Chain-of-Thought, CoT)与自洽性校验机制,支持多步推理、工…

作者头像 李华
网站建设 2026/6/9 22:19:50

Open-AutoGLM模型压缩技术全揭秘(稀有实战案例分享)

第一章:Open-AutoGLM模型压缩技术概述Open-AutoGLM 是一种面向大规模语言模型(LLM)的自动化模型压缩框架,专为 GLM 架构设计,旨在降低推理成本、提升部署效率,同时最大限度保留原始模型性能。该技术融合了剪…

作者头像 李华