Python 中的栈区(Stack)和堆区(Heap)浅解
2026/8/2 12:02:10 网站建设 项目流程

文章目录

    • @[TOC](文章目录)
  • 前言
    • 虽然 Python 底层依赖 C 语言的栈和堆,但 Python 对开发者屏蔽了这些细节。不过理解这个概念,对理解 Python 的内存管理和变量赋值非常有帮助。
  • 一、核心图解
  • 二、📖 详细解释
    • 1.栈区(Stack)
    • 2.堆区(Heap)
    • 3.🔍 关键理解:变量是贴在对象上的标签
    • 4.实战验证
    • 5.📌 可变与不可变对象的区别
    • 6.总结对比表
    • 记忆口诀

前言

虽然 Python 底层依赖 C 语言的栈和堆,但 Python 对开发者屏蔽了这些细节。不过理解这个概念,对理解 Python 的内存管理和变量赋值非常有帮助。

一、核心图解

二、📖 详细解释

1.栈区(Stack)

  • 存放内容:变量名和它们指向的引用地址(也就是堆区对象的地址)

  • 特点:

    • 存储的是引用(指针),不是实际数据

    • 访问速度非常快(直接访问)

    • 大小固定,由系统管理

    • 遵循 LIFO(后进先出)原则

xm="小明"# 栈中存储变量名 xm,指向堆中的字符串"小明"age=18# 栈中存储变量名 age,指向堆中的整数 18dog1=Dog()# 栈中存储变量名 dog1,指向堆中的 Dog 实例对象

2.堆区(Heap)

  • 存放内容:所有实际的对象数据(字符串、数字、列表、实例等)

  • 特点:

    • 存储的是实际数据
    • 访问速度相对较慢(需要间接寻址)
    • 大小动态,由 Python 的垃圾回收机制管理
    • 所有对象都在堆区创建
# 堆中存储的实际数据name="小明"# "小明" 这个字符串对象在堆中age=18# 18 这个整数对象在堆中numbers=[1,2]# [1, 2] 这个列表对象在堆中# 列表中存储的是对堆中 1 和 2 的引用

3.🔍 关键理解:变量是贴在对象上的标签

在 Python 中,变量名实际上是一个贴在对象上的标签,而不是存储对象的盒子。

图解变量赋值

a=[1,2,3]# 创建列表对象,贴上标签 ab=a# 把标签 b 也贴到同一个对象上

4.实战验证

classDog:def__init__(self,name):self.name=name dog1=Dog("旺财")dog2=dog1# dog2 和 dog1 指向同一个堆区对象print(id(dog1))# 0x7f8a1c2d3e4f(堆区地址)print(id(dog2))# 0x7f8a1c2d3e4f(完全相同!)# 验证它们指向同一个对象print(dog1isdog2)# True# 修改 dog1,dog2 也跟着变(因为指向同一个堆区对象)dog1.name="来福"print(dog2.name)# "来福"(确实变了!)

5.📌 可变与不可变对象的区别

不可变对象(int, str, tuple)
修改时会创建新对象,重新绑定引用。

a=10# 栈中 a → 堆中地址 0xA0F0 (值10)a=20# 栈中 a → 堆中地址 0xA1F1 (值20,新创建)# 原来 0xA0F0 的 10 被垃圾回收了

可变对象(list, dict, 自定义对象)
修改时不会创建新对象,直接修改堆中的数据。

lst=[1,2]# 栈中 lst → 堆中地址 0xB0F0lst.append(3)# 堆中地址 0xB0F0 的列表内容变为 [1, 2, 3]# 栈中 lst 仍然指向 0xB0F0(没变!)

6.总结对比表

记忆口诀

栈存标签,堆存实物
变量是标签,不是盒子
修改可变对象,标签不动
修改不可变对象,标签换贴新实物

这个理解是 Python 内存管理的基石,掌握后对理解引用传递、深拷贝/浅拷贝、垃圾回收等问题会轻松很多!👍

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询