赞
踩
一、前言
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋值给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。
二、区别
1、直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的变量也会做相同的改变
- # 直接赋值
- dict_1 = {"key1":[1,2,3,4],"key2":"val2"}
- dict_2 = dict_1
- dict_1["key1"].append(5)
- print("dict_1内存地址:",id(dict_1),id(dict_1["key1"]),dict_1)
- print("dict_2内存地址:",id(dict_2),id(dict_2["key1"]),dict_2)
2、浅拷贝,只拷贝父对象,子对象只是引用内存地址(不会拷贝嵌套的对象)
- # 浅拷贝
- dict_1 = {"key1":[1,2,3,4],"key2":"val2"}
- dict_2 = dict_1.copy()
- dict_1["key1"].append(5)
- print("dict_1内存地址:",id(dict_1),id(dict_1["key1"]),dict_1)
- print("dict_2内存地址:",id(dict_2),id(dict_2["key1"]),dict_2)
备注:父对象的内存地址直接被拷贝到了一个新的电脑上,但是对于子对象只是引用了它的内存地址,并没有拷贝子对象里面可迭代的内容。如果子对象里面的内容修改后,被赋值的变量也会做相同的改变
3、深拷贝,父对象,子对象都会拷贝
- # 深拷贝代码
- dict_1 = {"key1":[1,2,3,4],"key2":"val2"}
- # 浅拷贝
- dict_2 = dict_1.copy()
- # 深拷贝
- dict_3 = copy.deepcopy(dict_1)
- dict_1["key1"].append(5)
- print("dict_1内存地址:",id(dict_1),id(dict_1["key1"]),dict_1)
- print("dict_2内存地址:",id(dict_2),id(dict_2["key1"]),dict_2)
- print("dict_3内存地址:",id(dict_3),id(dict_3["key1"]),dict_3)
备注:深拷贝的话,就直接将父对象,子对象的内容拷贝到了自己的电脑上。通俗点讲,浅拷贝的话就是藕断丝连,深拷贝的话就是绝交。在使用上,不得不去拷贝对象的时候,尽量使用深拷贝,因为浅拷贝的话,是引用子对象的内存地址。深拷贝的话主要就是用在了有嵌套对象。
接下来的话一张图进行展示:
4、面试题:不可变元组和可变列表深浅拷贝的区别
- a_tuple = (1,2)
- b = copy.copy(a_tuple)
- c = copy.deepcopy(a_tuple)
- print(b == c)
- print(id(b) == id(c))
- print(id(a_tuple))
- print(id(b))
- print(id(c))
-
- a_list = [3,4]
- b = copy.copy(a_list)
- c = copy.deepcopy(a_list)
- print(b == c)
- print(id(b) == id(c))
- print(id(a_tuple))
- print(id(b))
- print(id(c))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。