Python 可变类型与不可变类型的内存引用机制详解

Jasper
Jasper
发布时间:2026-10-13| 6人浏览过
原创

本文深入解析Python中可变与不可变数据类型的内存管理机制。通过id()函数查看内存地址,阐明变量赋值、函数传参及列表字典修改时的引用行为。重点对比整型、字符串等不可变类型与列表、字典等可变类型在值改变时内存地址的变化差异,揭示引用计数与对象创建的底层逻辑。

Python变量内存地址与ID函数基础

在Python中,一旦定义了数据,系统便会在内存中开辟一块空间来存储该变量的值,这块已分配的内存空间拥有唯一的内存地址。访问这块内存需要借助变量名,变量名实际上存储的是指向该内存地址的引用,但使用print()函数输出时,显示的是这块内存中实际存储的地址值。这属于Python的设计规范,无需过度纠结其实现细节。

若要获取变量在内存中的具体地址,可以使用内置的id()函数。

常规使用场景如下。

基本数据类型的变量赋值与引用

变量之间的赋值操作,本质上是将一个变量的内存地址传递给另一个变量。这样,两个变量便都指向内存中的同一块空间,因此这两个变量的值是相等的。


a = 1
b = a
print("a:%d  b:%d" % (a,b))
print(id(a))
print(id(b))
结果:
a:1  b:1
1711072016

此时,如果有第三个变量c的值与a相等,那么c的地址与a的地址也是一样的。这一点需要牢记。


a = 1
c = 1
print("a:%d  c:%d" % (a,c))
print(id(a))
print(id(c))
结果:
a:1  c:1
1711072016

若此时修改变量c的值,Python会在内存中新开辟一块空间来存储这个新值,并将这块新内存的地址赋值给c。


a = 1
c = 1
c = 2
print("a:%d  c:%d" % (a,c))
print(id(a))
print(id(c))
结果:
a:1  c:2
1711072032

基本数据类型作为函数参数的传递机制

接下来探讨基本数据类型作为函数参数的情况。

基本数据类型作为函数实参传递时,遵循同样的引用逻辑。


a = 1
print(id(a))
def func(x):
  print(id(x))
  x = 2
  print(id(x))
 
func(a)
结果:
1711072016

高级数据类型的引用与修改行为

对于列表、字典等高级数据类型的引用机制,情况有所不同。

列表和字典等高级数据类型的变量名同样存储变量的实际地址。当一个列表名赋值给另一个变量时,这两个变量便指向内存中的同一块地址。


list1 = [1,2,3]
list2 = list1
print(list1,list2)
print(id(list1),id(list2))
结果:
[1, 2, 3] [1, 2, 3]
57931896

需要注意的是,高级数据类型每次加载进内存时,其内存地址可能与上一次不同。

若此时修改list2的值,会影响list1的值,但两个变量在内存中的地址保持不变。这一点与基本数据类型的行为不同。


list1 = [1,2,3]
list2 = list1
print(list1,list2)
print(id(list1),id(list2))
list2.append(4)
print(list1,list2)
print(id(list1),id(list2))
 
结果:
[1, 2, 3] [1, 2, 3]
43841656
[1, 2, 3, 4] [1, 2, 3, 4]
43841656

若此时有第三个列表list3的值也是[1,2,3,4],可以推测list3的地址与list1的地址应该是一样的,但事实并非如此。如果有第三个列表list3的值也是[1,2,3,4],相当于在内存中新开辟一块内存来存储这个值。


list1 = [1,2,3]
list2 = list1
list3 = [1,2,3]
print(list1,list2,list3)
print(id(list1),id(list2),id(list3))
结果:
[1, 2, 3] [1, 2, 3] [1, 2, 3]
16775288 16776768

可变与不可变数据类型的核心区别

最后总结可变数据类型与不可变数据类型的核心区别。

在Python中,哪些是可变数据类型,哪些是不可变数据类型?可变数据类型包括列表list和字典dict;不可变数据类型包括整型int、浮点型float、字符串型string和元组tuple。

用一句话来概括上述过程就是:“Python中的不可变数据类型,不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象,而对于相同的值的对象,在内存中则只有一个对象,内部会有一个引用计数来记录有多少个变量引用这个对象;可变数据类型,允许变量的值发生变化,即如果对变量进行append、+=等这种操作后,只是改变了变量的值,而不会新建一个对象,变量引用的对象的地址也不会变化,不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。”

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。