在Python编程中,拷贝对象是一个常见的需求,但是根据拷贝对象的数据结构,Python提供了几种不同的拷贝方式:
1. 赋值操作符号 “=” :这是最简单的拷贝方式,但是它不会创建一个新的对象,而是创建一个新的引用指向原对象,如下图
可见,b 只是对 a 列表的引用,它们都指向同一个地址。
2. copy 模块中的 copy 函数:copy.copy(),也就是浅拷贝,它会创建一个新的对象,但是拷贝的行为只针对最表层的对象,对象内的元素(对象,Python中万物皆对象)不会发生拷贝。
举个栗子:
a 是一个嵌套的 list 对象,b 是 对 a 进行浅拷贝copy.copy()生成的一个新对象,它们的 id 不同。但是,对于它们内部的元素则没有进行拷贝,所以 a[3] 和 b[3] 的 id 相同,此时如果改变 a 中 a[3] 这个内部 list 的元素,则 b 中 b[3] 同样会被改变
注:上述例子并不说明浅拷贝之后,修改 a 的元素的值,b 的元素值就一定会改变,这要取决于修改这个元素在 Python 中是否是可变对象。
Python 对可变对象的定义:当对象的值发生改变,如果它的内存地址 (或者说id) 没有发生改变,那它就是一个可变对象;反之,则是不可变对象。所以,对于 Python 中的常用基本数据类型,可变对象包含 list、set、dict,不可变对象包含int、float、bool、str、tuple等。
以上述例子的 a,我们来修改它内部的不可变对象元素
可见,修改 a 的不可变对象元素,并不会影响到 b 中的元素的值。
3. copy 模块中的 deepcopy 函数:copy.deepcopy(),也就是深拷贝,它同样会创建新的对象,并且对于嵌套的数据类型,会逐层的进行拷贝。
举个栗子:
可见,此时 b 中的可变对象元素相较于 a 中的可变对象元素,都是不同的对象。
为加深印象,附图解析如下:
浅拷贝
深拷贝