深入解析Python对象机制:可变与不可变对象的本质区别

Noah
Noah
发布时间:2026-10-14| 7人浏览过
原创

本文深入解析Python中一切皆对象的机制,详细区分可变与不可变对象。通过id()、type()和value()三个维度,阐述整数、字符串、元组等不可变对象在修改时产生新ID的特性,以及列表、字典等可变对象保持ID不变的原理。结合函数传参示例,澄清引用传递与值传递的误区,揭示Python对象在内存中的实际行为。

Python对象基础:ID、类型与值

在Python语言中,所有数据均可视为对象。每个对象都具备三个核心属性:唯一的标识符(id)、类型(type)以及值(value)。

  1. 标识符(id):对象一旦创建,其内存地址即固定不变。该地址可通过内置函数id()获取,用于唯一标识该对象在内存中的位置。
  2. 类型(type):与id类似,对象的类型在创建后亦不可更改。类型决定了该对象支持的操作集及行为方式。
  3. 值(value):即对象所存储的具体数据内容。

判断一个对象是否可变,核心依据在于其value是否支持原地修改。

不可变对象特性与示例

不可变对象(Immutable Objects)

常见的不可变对象类型包括:

  1. 数值类型:int(整型)、float(浮点型)、complex(复数)。
  2. 字符串(string)。
  3. 元组(tuple)。
  4. 冻结集合(frozenset),即set的不可变版本。

通过具体代码示例,我们可以直观理解不可变对象的特性。

示例分析


>>> x=1
>>> y=x
>>> id(x)==id(y)
True
>>> id(1)==id(y)
True

此处创建两个整型对象,令变量x和y指向同一对象。随后尝试对x执行x+1操作,观察其变化。


>>>x=x+1

此时,x的id、y的id以及常量1的id是否依然相同?


>>> x=x+1
>>> id(x)==id(y)
False
>>> id(x)==id(1)
False
>>> id(1)==id(y)
True

运行结果清晰表明,x所指向的对象已发生改变(生成了新对象),但常量1本身并未改变。这正是不可变对象的定义:一旦创建,其值无法被修改。若需“修改”,实际是创建了新对象并重新绑定变量。

注意:不可变并非绝对意义上的“不可改变”。


>>> a=([1],2,3)
>>> id(a)
4338862696
>>> id(a[0])
4338949128
>>> a[0][0]=0
>>> id(a)
4338862696
>>> id(a[0])
4338949128

从上述示例可见,修改容器内元素a[0]的值,并未改变容器a本身的id。若不可变容器(如元组)包含对可变对象(如列表)的引用,当内部可变对象的值改变时,容器的value也会随之变化;但由于容器的id(内存地址)未变,该容器仍被归类为不可变对象。

可变对象特性与示例

可变对象(Mutable Objects)

常见的可变对象类型包括:

  1. 列表(list)。
  2. 字典(dict)。
  3. 集合(set)。

同样通过示例来验证可变对象的行为。

示例分析


>>> c = [1,2,3]
>>> b = c
>>> id(b)==id(c)
True

创建两个列表对象,令变量c和d指向同一对象。随后尝试修改c的内容。


c[0]=4

此时检查两个对象的id值是否一致?


>>> id(c)==id(b)
True

修改后,c和d依然指向同一个内存地址。结论明确:对于可变对象,修改其value值不会改变其id,即原地修改生效。

函数参数传递机制解析

函数参数传递机制

可变对象与不可变对象在作为函数参数传递时,表现出显著差异。

示例对比

示例0:针对可变对象(列表)


def update_list(nums_list):
  print(f'2 id:{id(nums_list)}')
  nums_list += [10]
  print(f'3 id:{id(nums_list)}')

  
number_list = [5, 6]
print(f'1:{number_list}, id:{id(number_list)}')   
update_list(number_list)
print(f'4:{number_list}, id:{id(number_list)}') 

观察输出结果:

1:[5, 6], id:4457707912 2 id:4457707912 3 id:4457707912 4:[5, 6, 10], id:4457707912

再看另一个示例:

示例1:针对不可变对象(整数)


def add_num(number):
  print(f'2:{id(number)}')
  number += 1
  print(f'3:{id(number)}')


num = 1
print(f'1:{num}, id:{id(num)}')   
add_num(num)
print(f'4:{num}, id:{id(num)}')   

观察输出结果:

1:1, id:4343768416 2 id:4343768416 3 id:4343768448 4:1, id:4343768416

部分文章将上述eg0称为“引用传递”,eg1称为“值传递”。然而,Python官方文档中并未定义这两个术语,或者Python的传参机制并非简单的引用或值传递。

核心要点在于:对于可变对象,函数内部对值的修改会直接影响原对象;对于不可变对象,函数内部的修改仅作用于局部副本,不影响外部原对象。

以上为Python可变与不可变对象的详细解析。如需了解更多Python相关知识,请持续关注本站后续文章。

相关标签:

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

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 算法库。