首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第7章 编程术语
7.1 编程术语定义
7.1.1 作为语言的Python和作为解释器的Python
7.1.2 垃圾回收
7.1.3 字面量
7.1.4 关键字
7.1.5 对象、值、实例和身份
7.1.6 项
7.1.7 可变和不可变
7.1.8 索引、键和哈希值
7.1.9 容器、序列、映射和集合类型
7.1.10 特殊方法
7.1.11 模块和包
7.1.12 可调用对象和头等对象
7.2 经常被混淆的术语
7.2.1 语句和表达式
7.2.2 块、子句和主体
7.2.3 变量和特性
7.2.4 函数和方法
7.2.5 可迭代对象和迭代器
7.2.6 语法错误、运行时错误和语义错误
7.2.7 形参和实参
7.2.8 显式类型转换和隐式类型转换
7.2.9 属性和特性
7.2.10 字节码和机器码
7.2.11 脚本和程序,以及脚本语言和编程语言
7.2.12 库、框架、SDK、引擎、API
第8章 常见的Python陷阱
8.1 循环列表的同时不要增删其中的元素
8.2 复制可变值时务必使用copy.copy()和copy.deepcopy()
8.3 不要用可变值作为默认参数
8.4 不要通过字符串连接创建字符串
8.5 不要指望sort()按照字母顺序排序
8.6 不要假设浮点数是完全准确的
8.7 不要使用链式!=运算符
8.8 不要忘记在仅有一项的元组中添加逗号
第9章 Python的奇特难懂之处
9.1 为什么256 是256,而257 不是257
9.2 字符串驻留
9.3 假的Python 增量运算符和减量运算符
9.4 传递空列表给all()
9.5 布尔值是整数值
9.6 链式使用多种运算符
9.7 Python 的反重力特性
当前位置:
首页>>
技术小册>>
Python编程轻松进阶(三)
小册名称:Python编程轻松进阶(三)
### 8.2 复制可变值时务必使用`copy.copy()`和`copy.deepcopy()` 在Python编程中,理解并掌握如何正确复制对象,尤其是可变对象(如列表、字典、集合等),是进阶编程的重要一步。不当的复制操作往往会导致意想不到的副作用,如数据被意外修改、内存泄露或逻辑错误。因此,在《Python编程轻松进阶(三)》的本章中,我们将深入探讨`copy`模块中的两个关键函数:`copy.copy()`和`copy.deepcopy()`,以及它们在复制可变值时的应用与区别。 #### 8.2.1 理解可变与不可变对象 在深入探讨复制机制之前,首先需要明确Python中对象的可变性与不可变性。Python中的对象根据其值是否可以在不改变对象身份的情况下被修改,被分为可变对象和不可变对象。 - **不可变对象**:一旦创建,其值就不能被改变。常见的不可变对象包括整数(int)、浮点数(float)、字符串(str)和元组(tuple)。 - **可变对象**:其值可以被修改。常见的可变对象有列表(list)、字典(dict)、集合(set)以及用户定义的类实例(如果类中定义了可变属性)。 理解这一点对于掌握复制机制至关重要,因为复制可变对象时,我们关心的是对象的值本身是否在新的容器中独立存在,还是仅仅复制了对原始对象的引用。 #### 8.2.2 浅复制(Shallow Copy)与`copy.copy()` **浅复制**是指创建一个新的对象,这个新对象有着原始对象的一个精确副本,但如果原始对象中的元素是可变的,那么这些元素在新对象中的副本实际上是对原始元素的引用。这意味着,如果你修改了新对象中某个可变元素的值,那么这个修改也会反映到原始对象中。 `copy.copy()`函数就是用来执行浅复制的。它创建了一个新对象,并尝试将原始对象的所有属性复制到新对象中。但是,对于列表、字典等包含可变元素的容器,它只会复制容器的结构,而不会递归地复制容器内的可变元素。 ```python import copy original_list = [1, 2, [3, 4]] shallow_copy_list = copy.copy(original_list) # 修改浅复制列表中嵌套列表的元素 shallow_copy_list[2][0] = 5 # 原始列表也被修改了 print(original_list) # 输出: [1, 2, [5, 4]] print(shallow_copy_list) # 输出: [1, 2, [5, 4]] ``` 从上面的例子可以看出,尽管我们是在`shallow_copy_list`上进行了修改,但这一修改也影响到了`original_list`。 #### 8.2.3 深复制(Deep Copy)与`copy.deepcopy()` **深复制**则不同,它不仅复制了对象本身,还递归地复制了对象中所包含的所有子对象,从而创建了一个完全独立的新对象。这意味着,即使原始对象中的元素是可变的,这些元素在新对象中的副本也是完全独立的,修改它们不会影响原始对象。 `copy.deepcopy()`函数用于执行深复制。它会递归地复制原始对象中的所有元素,确保新对象与原始对象在内存中是完全独立的。 ```python import copy original_list = [1, 2, [3, 4]] deep_copy_list = copy.deepcopy(original_list) # 修改深复制列表中嵌套列表的元素 deep_copy_list[2][0] = 5 # 原始列表未受影响 print(original_list) # 输出: [1, 2, [3, 4]] print(deep_copy_list) # 输出: [1, 2, [5, 4]] ``` 在上面的例子中,修改`deep_copy_list`中的嵌套列表不会影响到`original_list`,这正是深复制所期望的行为。 #### 8.2.4 选择浅复制还是深复制? - **当你只需要复制容器结构,且容器内的元素是不可变对象时**,浅复制就足够了。 - **当容器内包含可变对象,且你希望这些可变对象在新容器中完全独立时**,应该使用深复制。 深复制虽然功能强大,但相比浅复制,它会消耗更多的内存和时间,因为它需要递归地复制所有子对象。因此,在选择复制方式时,应根据实际需求仔细权衡。 #### 8.2.5 注意事项 - **循环引用**:在使用`copy.deepcopy()`时,如果对象之间存在循环引用(即对象通过某种方式间接或直接地引用了自己),可能会导致无限递归,从而引发`RecursionError`。Python的`copy`模块在处理这种情况时有一定的机制来避免无限递归,但开发者仍需注意这一点。 - **自定义对象**:对于自定义的类对象,`copy.copy()`和`copy.deepcopy()`的行为可以通过定义类的`__copy__()`和`__deepcopy__()`特殊方法来控制。 #### 8.2.6 结论 在Python编程中,正确理解和使用`copy.copy()`和`copy.deepcopy()`是处理可变对象复制的关键。浅复制适用于简单场景,而深复制则提供了更强的数据独立性。通过合理选择复制方式,可以避免许多常见的编程错误,提高代码的健壮性和可维护性。希望本章的内容能帮助你更好地掌握这一重要概念,从而在Python编程的道路上更进一步。
上一篇:
8.1 循环列表的同时不要增删其中的元素
下一篇:
8.3 不要用可变值作为默认参数
该分类下的相关小册推荐:
Python与办公-玩转Excel
Python与办公-玩转PDF
Python高并发编程与实战
Python机器学习实战
Python数据分析与挖掘实战(上)
Python高性能编程与实战
Python合辑6-字典专题
Python合辑8-变量和运算符
Python编程轻松进阶(四)
Python机器学习基础教程(下)
Python合辑13-面向对象编程案例(上)
Python合辑10-函数