python_0">(python)区分深拷贝与浅拷贝
当我们在对不可变对象与可变对象进行拷贝操作时会有细微的区别,下面我以自己测试的结果来展开分析它们之间的细微区别。
在(python)中可变对象有:
字典,列表,集合,自定义的对象等;
不可变对象有:
数字,字符串,元祖,function等;
测试的重点:拷贝后a(源对象)与b(拷贝后的对象)地址是共享还是独立
首先对可变对象list进行测试:
python">#测试列表浅拷贝与深拷贝
import copy
def textCopy():
'''测试浅拷贝'''
#不拷贝子对象的内容,只拷贝了子对象的引用
a=[10,20,[5,6]]
b=copy.copy(a)
print("a",a)
print("b",b)
print("浅拷贝......")
print("a",a)
print("b",b)
print("a引用的对象的地址{0}".format(id(a)))
print("b引用的对象的地址{0}".format(id(b)))
print("a[2]引用的对象的地址{0}".format(id(a[2])))
print("b[2]引用的对象的地址{0}".format(id(b[2])))
print("a[0]引用的对象的地址{0}".format(id(a[0])))
print("b[0]引用的对象的地址{0}".format(id(b[0])))
print("a is b:",a is b)
print("a[2] is b[2]:",a[2] is b[2])
textCopy()
def textDeepCopy():
'''测试深拷贝'''
#会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象
a=[10,20,[5,6]]
b=copy.deepcopy(a)
print('a',a)
print('b',b)
print("深拷贝......")
print('a',a)
print('b',b)
print("a引用的对象的地址{0}".format(id(a)))
print("b引用的对象的地址{0}".format(id(b)))
print("a[2]引用的对象的地址{0}".format(id(a[2])))
print("b[2]引用的对象的地址{0}".format(id(b[2])))
print("a[0]引用的对象的地址{0}".format(id(a[0])))
print("b[0]引用的对象的地址{0}".format(id(b[0])))
print("a is b:", a is b)
print("a[2] is b[2]:",a[2] is b[2])
print("*"*20)
textDeepCopy()
总结一下:
1.列表浅拷贝后a,b是独立地址,但是a和b里面的可变对象是共享地址
2.列表深拷贝后a,b是独立地址,且a和b里面的可变对象也是独立地址
列表的浅拷贝经历了这样一个过程:
列表的深拷贝:
对不可变元祖进行测试
python">#测试元祖的深浅拷贝
import copy
def textCopy():
'''测试浅拷贝'''
#不拷贝子对象的内容,只拷贝了子对象的引用
a=(10,20,[5,6])
b=copy.copy(a)
print("a",a)
print("b",b)
print("浅拷贝......")
print("a",a)
print("b",b)
print("a引用的对象的地址{0}".format(id(a)))
print("b引用的对象的地址{0}".format(id(b)))
print("a[2]引用的对象的地址{0}".format(id(a[2])))
print("b[2]引用的对象的地址{0}".format(id(b[2])))
print("a[0]引用的对象的地址{0}".format(id(a[0])))
print("b[0]引用的对象的地址{0}".format(id(b[0])))
print("a is b:",a is b)
print("a[2] is b[2]:",a[2] is b[2])
textCopy()
def textDeepCopy():
'''测试深拷贝'''
#会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象
a=(10,20,[5,6])
b=copy.deepcopy(a)
print('a',a)
print('b',b)
print("深拷贝......")
print('a',a)
print('b',b)
print("a引用的对象的地址{0}".format(id(a)))
print("b引用的对象的地址{0}".format(id(b)))
print("a[2]引用的对象的地址{0}".format(id(a[2])))
print("b[2]引用的对象的地址{0}".format(id(b[2])))
print("a[0]引用的对象的地址{0}".format(id(a[0])))
print("b[0]引用的对象的地址{0}".format(id(b[0])))
print("a is b:", a is b)
print("a[2] is b[2]:",a[2] is b[2])
print("*"*20)
textDeepCopy()
浅拷贝运行结果:
深拷贝运行结果:
总结一下:
1.元祖浅拷贝后a,b共享地址,且a和b里面的可变对象也是共享地址
2.元祖深拷贝后a,b是独立地址,且a和b里面的可变对象也是独立地址
浅拷贝过程:
深拷贝过程:
对不可变对象数字和字符串测试
这里数字和字符串测试结果相同,我就以字符串为列
python">#测试不可变对象数字及字符串的浅拷贝和深拷贝
import copy
def shuzicopy():
'''测试字符串浅拷贝'''
a='jqwdko'
b=copy.copy(a)
print(id(a))
print(id(b))
print(a is b)
shuzicopy()
def shuzideepcopy():
'''测试字符串深拷贝'''
a='jqwdko'
b=copy.deepcopy(a)
print(id(a))
print(id(b))
print(a is b)
print("_"*10)
shuzideepcopy()
运行结果:
总结:字符串与数字的深浅拷贝的效果一样:
拷贝后a,b都是共享地址