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/10 13:30:20

为什么顶尖AI团队都在关注Open-AutoGLM?(开源自动化新纪元)

第一章:Open-AutoGLM的崛起与行业影响Open-AutoGLM作为新一代开源自动化语言模型框架,凭借其模块化架构与高效推理能力,迅速在人工智能领域引发广泛关注。该框架融合了自然语言理解、代码生成与自主任务规划能力,为开发者提供了从…

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

(9-3-05)智能编程助手(IDA Pro+VS Code+MCP):变量与函数修改操作

本部分的主要功能是提供对程序元素的修改能力,支持重命名局部变量、全局变量和函数,设置全局变量和局部变量的类型,以及修改函数原型。可以读取全局变量的编译时值,例如从C语言声明创建或更新自定义类型,并能刷新反编译…

作者头像 李华
网站建设 2026/6/10 12:49:20

Dify镜像支持Spinnaker实现蓝绿部署

Dify镜像与Spinnaker集成实现蓝绿部署的实践路径 在AI应用快速落地的今天,企业面临的不仅是模型能力的竞争,更是工程化交付效率和系统稳定性的较量。一个精心调优的智能客服Agent,如果因为一次发布导致服务中断几分钟,用户体验可能…

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

Dify如何实现意图识别引导对话流程?

Dify如何实现意图识别引导对话流程? 在智能客服频繁“答非所问”、对话机器人陷入死循环的今天,构建一个真正理解用户意图并能动态响应的AI系统,依然是企业落地大模型应用的核心挑战。用户一句“我想退掉昨天买的鞋子”,系统不仅要…

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

eide串口下载配置图解说明

eide 串口下载配置实战指南:从原理到一键烧录的完整解析 你有没有遇到过这样的场景? 明明代码编译通过了,点击“下载”按钮却卡在90%,提示“Sync failed”; 反复插拔USB线、按复位键十几次,还是进不了IS…

作者头像 李华
网站建设 2026/6/10 13:35:28

3步搞定B站硬核会员:AI自动答题终极指南

3步搞定B站硬核会员:AI自动答题终极指南 【免费下载链接】bili-hardcore bilibili 硬核会员 AI 自动答题,直接调用 B 站 API,非 OCR 实现 项目地址: https://gitcode.com/gh_mirrors/bi/bili-hardcore 还在为B站硬核会员的100道题目感…

作者头像 李华