2026/1/13 11:16:14
网站建设
项目流程
安阳网站制作优化,金州新区规划建设局网站,足球排行榜前十名,深圳外贸建站网络推广哪家好1、浅拷贝(Shallow Copy)浅拷贝是对于一个对象的顶层拷贝。创建一个新对象,但只复制原对象的第一层元素(顶层容器),而不复制嵌套的子对象2、深拷贝(Deep Copy)深拷贝是对一个对象所有层次的拷贝(递归)。创建一个完全独立的新对象,递归复制所有层级的元素,包括嵌套的子对象。深拷…1、浅拷贝(Shallow Copy)浅拷贝是对于一个对象的顶层拷贝。创建一个新对象,但只复制原对象的第一层元素(顶层容器),而不复制嵌套的子对象2、深拷贝(Deep Copy)深拷贝是对一个对象所有层次的拷贝(递归)。创建一个完全独立的新对象,递归复制所有层级的元素,包括嵌套的子对象。深拷贝的实现机制当执行 copy.deepcopy()时首先检查对象是否已经在备忘录(memo)字典中(防止循环引用)然后检查对象类型:如果是不可变类型,直接返回原对象如果是可变类型,创建新对象并递归复制内容对于自定义类,会调用 __deepcopy__()方法(如果存在)下面分别从赋值,浅拷贝,深拷贝三个示例代码来说明差异:赋值示例代码如下:#!/usr/bin/python3 # 赋值操作() a [1,2,[3,4]] b a # 赋值后两个对象的内存地址都一样,只是创建新引用,不复制数据,说明b是a的引用,b改变会同样影响a print(a0x%x,b0x%x %(id(a),id(b))) # a0x731bd8350dc0,b0x731bd8350dc0 # a[0]0x731bd8cc40f0,b[0]0x731bd8cc40f0 print(a[0]0x%x,b[0]0x%x %(id(a[0]),id(b[0]))) # a[1]0x731bd8cc4110,b[1]0x731bd8cc4110 print(a[1]0x%x,b[1]0x%x %(id(a[1]),id(b[1]))) # a[2]0x731bd8db86c0,b[2]0x731bd8db86c0 print(a[2]0x%x,b[2]0x%x %(id(a[2]),id(b[2]))) # a[2][0]0x731bd8cc4130,b[2][0]0x731bd8cc4130 print(a[2][0]0x%x,b[2][0]0x%x %(id(a[2][0]),id(b[2][0]))) b[0] 99 print(a) # [99, 2, [3, 4]] print(b) # [99, 2, [3, 4]] b[2][0] 88 print(a) # [99, 2, [88, 4]] print(b) # [99, 2, [88, 4]]浅拷贝示例代码如下:#!/usr/bin/python3 import copy # 浅拷贝创建一个新对象,但只复制原对象的第一层元素(顶层容器),而不复制嵌套的子对象 a [1,2,[3,4]] b copy.copy(a) # a,b内存地址不同,说明不是引用,是两个不同的对象 print(a0x%x,b0x%x %(id(a),id(b))) # a0x7b0be03e44c0,b0x7b0be03e4480 # a[0]0x7b0be0e900f0,b[0]0x7b0be0e900f0,顶层元素内存地址一样(int为不可变类型,共享地址,所以地址一样,确实发生了拷贝动作) print(a[0]0x%x,b[0]0x%x %(id(a[0]),id(b[0]))) # a[1]0x7b0be0e90110,b[1]0x7b0be0e90110 print(a[1]0x%x,b[1]0x%x %(id(a[1]),id(b[1]))) # a[2]0x7b0be03e4440,b[2]0x7b0be03e4440,嵌套元素内存地址一样(列表为可变类型,说明嵌套元素确实是浅拷贝) # a中嵌套元素值的改变同样会影响b中嵌套元素值的内容 print(a[2]0x%x,b[2]0x%x %(id(a[2]),id(b[2]))) # a[2][0]0x7b0be0e90130,b[2][0]0x7b0be0e90130,a[2][0]和b[2][0]内存地址一样 print(a[2][0]0x%x,b[2][0]0x%x %(id(a[2][0]),id(b[2][0]))) # 修改顶层元素 b[0] 99 print(a) # [1, 2, [3, 4]],a[0]值不变 print(b) # [99, 2, [3, 4]] # 修改嵌套元素 b[2][0] 88 print(a) # [1, 2, [88, 4]],a[2][0]值发生变化,原对象被修改 print(b) # [99, 2, [88, 4]]深拷贝示例代码如下:#!/usr/bin/python3 import copy # 深拷贝创建一个完全独立的新对象,递归复制所有层级的元素,包括嵌套的子对象 a [1,2,[3,4]] b copy.deepcopy(a) # 内存地址不同,说明不是引用,是两个不同的对象 print(a0x%x,b0x%x %(id(a),id(b))) # a0x768e7e8e02c0,b0x768e7e8e0280 # a[0]0x768e7eb000f0,b[0]0x768e7eb000f0,顶层元素内存地址一样(int为不可变类型,共享地址,所以地址一样,确实发生了拷贝动作) print(a[0]0x%x,b[0]0x%x %(id(a[0]),id(b[0]))) # a[2]0x7feede8c43c0,b[2]0x7feede8c5a80,嵌套元素内存地址不一样,说明嵌套列表是两个不同的对象,发生了拷贝动作(列表为可变类型) print(a[2]0x%x,b[2]0x%x %(id(a[2]),id(b[2]))) # a[2][0]0x768e7eb00130,b[2][0]0x768e7eb00130 print(a[2][0]0x%x,b[2][0]0x%x %(id(a[2][0]),id(b[2][0]))) # 修改顶层元素 b[0] 77 print(a) # [1, 2, [3, 4]] print(b) # [77, 2, [3, 4]] # 修改底层元素 b[2][0] 66 print(a) # [1, 2, [3, 4]] print(b) # [77, 2, [66, 4]]Q:为什么深拷贝后,对象内部某些类型的id()值还是一样A:在Python中,深拷贝后两个对象的id()值有时会相同,这看起来似乎违反了深拷贝的预期行为。但实际上这是由Python的对象模型和深拷贝的实现机制决定的。核心原因:不可变对象的优化Python对不可变对象(immutable objects)有特殊处理当深拷贝一个不可变对象时,Python会直接返回原始对象而不是创建新副本因为不可变对象无法被修改,共享引用是安全的,这样可以节省内存和提高性能常见不可变对象类型数字类型:int, float, complex布尔值:bool字符串:str元组:tuple(当所有元素都是不可变时)冻结集合:frozenset字节串:bytes示例代码如下#!/usr/bin/python3 import copy # 不可变对象(整数) a 256 b a # 赋值 print(a is b) # True print(id(a) id(b)) # True b 128 print(a,b) # 256 128 c copy.deepcopy(a) # 深拷贝 print(c is a) # True print(id(c) id(a)) # True c 128 print(a,b,c) # 256 128 128 # 不可变对象(字符串) s1 python s2 copy.deepcopy(s1) print(s1 is s2) # True print(id(s1) id(s2)) # True s3 s2.replace(t,a,1) print(s3 is s1) # False s4 s1 print(s4 is s1) # True # 不可变对象(元组) t1 (1,a,(3,4)) t2 copy.deepcopy(t1) print(t1 is t2) # True print(id(t1) id(t2)) # True t3 ([1,2],b) #元组包含可变对象 t4 copy.deepcopy(t3) print(t3 is t4) # False print(id(t3) id(t4)) # False print(id(t3[0]) id(t4[0])) # False # 可变对象(列表) l1 [1,2,[3,4]] l2 copy.deepcopy(l1) print(l1 is l2) # False print(id(l1) id(l2)) # False print(id(l1[2]) id(l2[2])) # False