Python中淺拷貝和深拷貝的區別
淺拷貝和深拷貝示意圖
如上圖,簡單點說
1. copy.copy 淺拷貝 只拷貝父對象,不會拷貝對象的內部的子對象。
2. copy.deepcopy 深拷貝 拷貝對象及其子對象
數字,字符串是不可變類型
列表,字典是可變類型
我們看下面的案例
案例一:淺拷貝
>>> import copy #導入copy模塊 >>> s=['name',['savings',100.0]] #賦值給s >>> t=copy.copy(s) #將s淺拷貝給t >>> s ['name', ['savings', 100.0]] >>> t ['name', ['savings', 100.0]] >>> id(s) 139814645224224 >>> id(t) 139814645264184 #查看s和t的內存空間地址,發現s和t的內存空間地址不一樣 >>> id(s[0]) 139814648512112 >>> id(t[0]) 139814648512112 >>> id(s[1]) 139946237132672 >>> id(t[1]) 139946237132672 #查看s和t的子對象的內存空間地址,發現s和t的子對象的內存空間地址一樣 #以上證明淺拷貝只拷貝父對象,不會拷貝對象的內部的子對象 >>> s.append('age') >>> s ['name', ['savings', 100.0], 'age'] >>> t ['name', ['savings', 100.0]] #s添加'age'字符串,但是t並沒有添加 >>> s[0]='job' >>> s ['job', ['savings', 100.0], 'age'] >>> t ['name', ['savings', 100.0]] >>> s[1][1]=200.0 >>> s ['job', ['savings', 200.0], 'age'] >>> t ['name', ['savings', 200.0]] #當我們修改s的'name'時t並沒有修改,但是當我修改s的100.0時t也被修改了 #數字、字符串是不可變類型,t並不會跟着s一起被修改 #列表,字典爲可變類型,t會隨s的修改而被修改,100.0是屬於s裏的列表的值
案例二:深拷貝
>>> import copy #導入copy模塊 >>> s=['name',['savings',100.0]] #賦值給s >>> t=copy.deepcopy(s) #將s淺拷貝給t >>> s ['name', ['savings', 100.0]] >>> t ['name', ['savings', 100.0]] #查看s和t的值 >>> id(s) 140329642791784 >>> id(t) 140329642793080 #查看s和t的內存空間地址,發現s和t的內存空間地址不一樣 >>> id(s[0]) 140329646079600 >>> id(t[0]) 140329646079600 #查看s和t的子對象'name'的內存空間地址,發現s和t的子對象'name'的內存空間地址一樣 >>> id(s[1]) 140329642729344 >>> id(t[1]) 140329642831240 #查看s和t的子對象['savings',100.0]的內存空間地址,發現s和t的子對象['savings',100.0]的內存空間地址不一樣 #以上證明深拷貝會拷貝對象及其子對象 >>> s.append('age') >>> s ['name', ['savings', 100.0], 'age'] >>> t ['name', ['savings', 100.0]] #s添加'age'字符串,但是t並沒有添加 >>> s[0]='job' >>> s ['job', ['savings', 100.0]] >>> t ['name', ['savings', 100.0]] >>> s[1][1]=200.0 >>> s ['name', ['savings', 200.0], 'age'] >>> t ['name', ['savings', 100.0]] #當我們修改s的'name'時t沒有被修改,但是當我修改s的100.0時t也沒被修改 #證明s和t是完全分離開來的,沒有任何關聯
總結:
淺拷貝時,當我們修改s的子對象(字典和列表等可變類型)時,t也會跟着改變。但是s添加對象時,t並不會添加
深拷貝時,s和t的內容完全分離開來,添加或修改s的對象時t並不會跟着改變