对象类型

  • 不可变对象:一旦创建就不可修改的对象,包括字符串、元组、数值类型 (该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。)

  • 可变对象:可以修改的对象,包括列表、字典、集合

赋值与深浅拷贝

  • 不可变对象类型

没有被拷贝的说法,深浅拷贝和赋值是一样的。

  • 可变对象类型
  1. 赋值: 只是复制了新对象的引用,不会开辟新的内存空间。

并不会产生一个独立的对象单独存在,只是将原有的数据块打上一个新标签,所以当其中一个标签被改变的时候,数据块就会发生变化,另一个标签也会随之改变。

  1. 浅拷贝: 创建新对象,其内容是原对象的引用。

浅拷贝有三种形式: 切片操作,工厂函数,copy模块中的copy函数。

如: lst = [1,2,[3,4]]

切片操作:lst1 = lst[:] 或者 lst1 = [each for each in lst]

工厂函数:lst1 = list(lst)

copy函数:lst1 = copy.copy(lst)

浅拷贝之所以称为浅拷贝,是它仅仅只拷贝了一层,拷贝了最外围的对象本身。

  1. 深拷贝:和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。深拷贝出来的对象是一个全新的对象,不再与原来的对象有任何关联。

只有一种形式,copy模块中的deepcopy函数.

举例:l = [1,2,3,[4, 5]],其中[4, 5]是内层对象,1、2、3是外层。 ### 总结
1. 赋值对象随着原对象一起变化。 2. 外层添加元素时,浅拷贝不会随原对象变化而变化;内层添加元素时,浅拷贝才会变化。 3. 无论原对象如何变化,深拷贝都保持不变。

参考链接:

函数传递参数

Python的参数传递就是将对象赋值给另一个变量(起了另外一个名字),所以对于可变对象来说,如果不想调用的函数对其修改的话,需要传递深拷贝或浅拷贝(对象内部没有深一层对象会被改变)。 例如:

1
2
3
4
5
6
7
def function(l):
l.append('no')
L = [1, 3]
function(L[:]) #传递一个浅拷贝
print(L)
## 输出应为[1, 3]
## 如果传递参数时没有进行浅拷贝:function(L),那么输出就会变成[1, 3, 'no'].