python中copy模块的两个参数对比
先创建一个字典就搬朋友的例子来说明了
>>> import copy
>>> n1 = {"k1":123,"k2":"hehe","k3":[456,"number"]}
>>> a = n1
>>> b = copy.copy(n1) #浅复制
>>> c = copy.deepcopy(n1) #深复制
执行结果没有不会有什么变化
>>> n1 {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'} >>> a {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'} >>> b {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'} >>> c {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
一切皆内存来看一下内存地址,结果表明 n1与 a 相同 b c 均为独立开辟新地址
>>> id(n1) 37621592 >>> id(a) 37621592 >>> id(b) 24503240 >>> id(c) 37886752
在上面的实例中使用了 copy.copy 与copy.deepcopy 对同一个字典n1 做复制操作,其中n1 字典中包含了一个字典即“k3”
通过各键的对比可以发现,除了 c 的“k3”以外,其他变量中的键值的指针都是指向了n1的内存空间
n1
>>> id(n1["k1"]) 1568402192 >>> id(n1["k2"]) 37906752 >>> id(n1["k3"]) 37440408
a
>>> id(a["k1"]) 1568402192 >>> id(a["k2"]) 37906752 >>> id(a["k3"]) 37440408
b
>>> id(b["k1"]) 1568402192 >>> id(b["k2"]) 37906752 >>> id(b["k3"])
37440408
c
>>> id(c["k1"]) 1568402192 >>> id(c["k2"]) 37906752 >>> id(c["k3"]) 37430896
上面的数据未经过修改,那先测试修改“k1”的值,将123改为456看看内存地址发生了什么变化。赋值结果已经有了区别,可以看到 n1 与 a 保持一致 b 与 c 保持一致
>>> n1 {'k1': 456, 'k3': [456, 'number'], 'k2': 'hehe'} >>> a {'k1': 456, 'k3': [456, 'number'], 'k2': 'hehe'} >>> b {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'} >>> c {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
看一下现在的内存位置,经过对比可以发现此时更改了 “k1”的键值,变量的内存指针不会发生变化。
>>> id(n1) 37621592 >>> id(a) 37621592 >>> id(b) 24503240 >>> id(c) 37886752
那么键值内存地址有没有发生变化呢?看一下。回顾上面的n1的“k1”结果,“k1”为37621592,当前“k1”值为37652576,这说明字典中每个键值都是由指针指向内存地址,修改过n1的“k1”值后 n1 开辟了新内存地址并将指针指向它,而且a也随着n1 的指针发生了改变。b和c依然指向之前的内存地址,这说明之前的内存地址并不会被释放,修改数据会重新开辟新的内存空间。
>>> id(n1["k1"]) 37652576 >>> id(a["k1"]) 37652576 >>> id(b["k1"]) 1568402192 >>> id(c["k1"]) 1568402192
做了这么多貌似并没有看出 copy.copy与copy.deepcopy的区别,下面我们就来看看两者之间的区别。实例中字典里含有一个列表,现在来修改列表中的内容做对比。将“k3”的值做修改
>>> n1 {'k1': 456, 'k3': [8888, 'number'], 'k2': 'hehe'} >>> a {'k1': 456, 'k3': [8888, 'number'], 'k2': 'hehe'} >>> b {'k1': 123, 'k3': [8888, 'number'], 'k2': 'hehe'} >>> c {'k1': 123, 'k3': [456, 'number'], 'k2': 'hehe'}
可以看到只有 c 没有发生改变,这是为什么呢?我想你现在已经可以理解了。做到这里就做个死得瞑目吧,接着看内存地址。
>>> id(n1["k3"]) 37440408 >>> id(a["k3"]) 37440408 >>> id(b["k3"]) 37440408 >>> id(c["k3"]) 37430896
>>> id(n1["k3"][0]) 37652208 >>> id(a["k3"][0]) 37652208 >>> id(b["k3"][0]) 37652208 >>> id(c["k3"][0]) 37613600
>>> id(n1["k3"][1])
31630560
>>> id(a["k3"][1])
31630560
>>> id(b["k3"][1])
31630560
>>> id(c["k3"][1])
31630560