Python中可变对象和不可变对象的使用详解

夏知夏
夏知夏
发布时间:2026-10-10| 2人浏览过
原创

Python将对象按创建后是否允许修改分为可变与不可变两类。掌握各类数据结构的行为特征及函数参数传递机制,能有效避免内存引用冲突与意外修改原始数据的开发陷阱。

1. 对象可变性简介与核心定义

在Python中,每个变量本质上都是指向堆内存中对象的引用。对象的可变性决定了其在传递给函数、参与表达式计算或存储于复合数据结构时的底层行为。核心分类如下:

  • 可变对象:创建后内部状态可被直接修改。典型代表包括列表(list)、字典(dict)、集合(set)及自定义类实例。
  • 不可变对象:创建后其内容或状态禁止修改。典型代表包括整数(int)、浮点数(float)、字符串(str)、元组(tuple)及冻结集合(frozenset)。

2. 不可变对象的行为特征

不可变对象在内存中具有固定地址与固定数据。任何看似“修改”的操作,实际上都是生成新对象并让变量指向它。

第1步:查看字符串与数字的修改机制

对字符串进行替换或对数字进行运算时,Python会在内存中开辟新空间存放结果,原对象保持不变。

str1 = "Hello"
# 尝试更改字符串的内容
str2 = str1.replace('H', 'J')
print(str1)  # 输出 Hello,原字符串未改变
print(str2)  # 输出 Jello,创建了一个新字符串

x = 10
y = x
x = x + 1
print(y)  # 输出 10,y 仍然指向原来的整数对象
print(x)  # 输出 11,x 现在指向一个新的整数对象

第2步:检查元组顶层与嵌套元素的可变性

元组的顶层结构严格不可变,但若其中包含可变对象(如列表),则该内部对象的属性仍可被修改。元组的不可变性仅作用于自身引用的绑定关系。

tup = (1, 2, 3)
try:
    tup[0] = 100  # 尝试修改元组的第一个元素
except TypeError as e:
    print(e)  # 输出错误信息(TypeError)

# 元组内含可变对象
tup_with_list = (1, [2, 3], 4)
tup_with_list[1].append(5)
print(tup_with_list)  # 输出 (1, [2, 3, 5], 4)

3. 可变对象的操作规则

可变对象允许在原有内存地址上直接增删改查,适合需要频繁更新数据的场景。

第3步:直接在原地更新列表与字典

列表追加元素或字典更新键值对时,内存地址不变,仅内部数据结构发生重排。

lst = [1, 2, 3]
lst.append(4)
print(lst)  # 输出 [1, 2, 3, 4],列表内容被修改

dic = {'a': 1, 'b': 2}
dic['c'] = 3
print(dic)  # 输出 {'a': 1, 'b': 2, 'c': 3},字典已更新

第4步:验证集合的元素添加限制

集合基于哈希表实现,要求所有元素必须是可哈希的(即不可变对象)。尝试添加列表或普通集合会触发异常。

# 创建一个初始集合
my_set = {1, 2, 3}
print("初始集合:", my_set)

# 添加、移除元素
my_set.add(4)
my_set.remove(2)
print("操作后的集合:", my_set)

nested_set = {1, 2, 3}
try:
    nested_set.add([4, 5, 6])  # 尝试添加列表到集合中
except TypeError as e:
    print(e)  # 输出错误信息

4. 函数参数传递的实际影响

Python采用“按对象引用传递”(Pass by Object Reference)机制。函数接收的是实参对象的内存地址,因此形参上的操作是否会波及外部变量,完全取决于该对象是否可变。

第5步:对比不可变与可变对象在传参时的输出结果

传入不可变对象时,函数内部的重新赋值或数学运算只会改变局部变量的指向,外部原始对象安全无损。传入可变对象时,函数内部的原地修改操作会直接反映到外部。

def update_number(n):
    n += 10

x = 5
update_number(x)
print(x)  # 输出 5,原始值未改变

def update_list(lst):
    lst.append(4)

my_list = [1, 2, 3]
update_list(my_list)
print(my_list)  # 输出 [1, 2, 3, 4],原始列表被修改

注意事项

在大型项目或并发环境中,依赖可变对象的隐式修改容易导致难以追踪的状态污染。建议在设计API接口或工具函数时,对外部传入的字典或列表使用copy()或deepcopy()建立本地副本,或在明确需求下显式返回新对象以隔离副作用。

以上就是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 算法库。