copy 浅复制 与深复制

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

 

posted on 2017-04-28 00:56  蓝码骑士  阅读(177)  评论(0编辑  收藏  举报

导航