一、前言
在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))
|