Python-引用&淺拷貝&深拷貝
阿新 • • 發佈:2021-12-06
淺拷貝: 指的是重新分配一塊記憶體,建立一個新的物件,但裡面的元素是原物件中各個子物件的引用
深拷貝: 指的是重新分配一塊記憶體,建立一個新的物件,並且將原物件中的元素,以遞迴的方式,通過建立新的子物件拷貝到新物件中
三十六般武藝,七十二般變化,修練出個人品牌併發出光芒#codding: utf-8 """ 常量值: 在整個程式的完整生命週期中只會建立一次的變數被稱為常量 1、str、int、 float、bool 這四個型別的值都是常量值,下面的例子中不論怎麼操作都不會建立一個新的值 """ import copy a = "cpython" #建立常量 b = a #引用 c = copy.copy(a) #淺拷貝 d = copy.deepcopy(a) #深拷貝 """ 執行結果: id(a) Out[12]: 140347862604464 id(b) Out[13]: 140347862604464 id(c) Out[14]: 140347862604464 id(d) Out[15]: 140347862604464 """ a = 10 #建立常量 b = a #引用 c = copy.copy(a) d = copy.deepcopy(a) id(a) Out[20]: 140348122786384 id(b) Out[21]: 140348122786384 id(c) Out[22]: 140348122786384 id(d) Out[23]: 140348122786384 a = 2.4 #建立常量 b = a #引用 c = copy.copy(a) d = copy.deepcopy(a) id(a) Out[28]: 140347862758640 id(b) Out[29]: 140347862758640 id(c) Out[30]: 140347862758640 id(d) Out[31]: 140347862758640 a = True #建立常量 b = a #引用 c = copy.copy(a) d = copy.deepcopy(a) id(a) Out[36]: 4502985424 id(b) Out[37]: 4502985424 id(c) Out[38]: 4502985424 id(d) Out[39]: 4502985424 #物件值:除了常量值以外,其他一切都是物件(類),例如:class, list, dict, tuple, set, queue, deque.... #物件的特徵是,每次例項化一個物件都會建立new一個新記憶體,因此每次例項化一個物件,它們的id都是獨立的 a = [] b = [] id(a) Out[42]: 140348133547520 id(b) Out[43]: 140347588520896 class TEST: def __init__(self): self.world = "world" a = TEST() b = TEST() id(a) Out[51]: 140348133753232 id(b) Out[52]: 140347862738592 #引用: python採取完全引用策略,所以像做下面這種操作,並不是複製/拷貝,而是引用 a = [] #例項化一個列表物件,變數a的指標指向該列表物件 b = a #變數b的指標指向a所指向的列表物件 id(a) Out[55]: 140348133760384 id(b) Out[56]: 140348133760384 ### 拷貝 a = [1,2,3,4] b = a c = copy.copy(a) d = copy.deepcopy(a) id(a) Out[61]: 140348135105280 id(b) Out[62]: 140348135105280 id(c) Out[63]: 140348135105664 #c分配了一塊新的記憶體 id(d) Out[64]: 140348133627136 #d分配了一塊新的記憶體 id(a[0]) Out[65]: 140348122786096 id(b[0]) Out[66]: 140348122786096 #成員值是常量,拷貝的是引用 id(c[0]) Out[67]: 140348122786096 #成員值是常量,拷貝的是引用 id(d[0]) Out[68]: 140348122786096 #成員值是常量,拷貝的是引用 ##淺拷貝 a = [1,2,3,[4,5,6]] b = a c = copy.copy(a) id(a[3]) Out[75]: 140348133697664 id(b[3]) Out[76]: 140348133697664 id(c[3]) Out[77]: 140348133697664 Out[77]: 140348133697664 a[3][0]= 10 #a[3]發生變化 Out[77]: 140348133697664 b #b[3]引用a[3],所以b[3]也發生變化 Out[79]: [1, 2, 3, [10, 5, 6]] c Out[80]: [1, 2, 3, [10, 5, 6]] b[3][1] = 20 #b[3]的子物件發生變化 b Out[82]: [1, 2, 3, [10, 20, 6]] a #a[3]的子物件也會發生變化 Out[83]: [1, 2, 3, [10, 20, 6]] c Out[84]: [1, 2, 3, [10, 20, 6]] #深拷貝 a = [1,2,3,[4,5,6]] b = copy.deepcopy(a) id(a) Out[87]: 140348133734144 #分配一塊新的記憶體 id(b) Out[88]: 140348133698496 #分配一塊新的記憶體 a[3][0]=10 a Out[90]: [1, 2, 3, [10, 5, 6]] #a物件中的子物件發生變化 b Out[91]: [1, 2, 3, [4, 5, 6]] #b物件中的子物件仍不變 ###結論: 1、不論是淺拷貝還是深拷貝,都不拷貝最終的常量值,而是引用 2、淺拷貝引用的是一維的成員 3、深拷貝遞迴的是建立物件,只有遇到常量值是會引用