深浅拷贝

  • 直接赋值:其实就是对象的引用

    a = [1,2,3]
    b = a
    print(a, b) # [1,2,3] [1,2,3]
    print(id(a),id(b)) # 4497919088 4497919088
    a = 5
    print(a, b) # 5 5
    print(id(a),id(b)) # 4498367856 4498367856
    

    b = a: 赋值引用,a 和 b 都指向同一个对象。

  • 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。

a = {1:[1,2,3]}

b = a.copy()

a[2] = a.pop(1)

a[2].append(4)

print(a,b) # [2:[1, 2, 3, 4]], [1: [1, 2, 3, 4]]

b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。

  • 深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

深度拷贝需要引入 copy 模块:

import copy 

a = {1:[1,2,3]}

c = copy.deepcopy(a) 

a[2] = a.pop(1)

a[2].append(5) 

print(a,c) # a, c ({2: [1, 2, 3, 5]}, {1: [1, 2, 3 ,5]})

浅拷贝:

浅拷贝它拷贝的是浅层次的数据结构(不可变元素int、float、str)被拷贝到了新的内存地址,对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去,而是和原对象里的可变元素指向同一个地址;
所以在新对象或原对象里对这个可变元素做修改时,两个对象是同时改变的。

深拷贝:

针对不可变,用原来的内存地址指向新的拷贝的地址(省空间)。

针对可变,开辟新得容器地址(这个新得容器里也会区分可变不可变类型,如果可变则又会开辟新得容器内存空间,如果是不可变类型则同样是共用原来得内存地址,以此类推)。

深拷贝就是区分了不可变与可变数据类型;对于不可变数据类型直接复制内存地址到新的地址上;对于可变数据类型,再开辟一块内存空间来保存可变数据的内存地址。