zoukankan      html  css  js  c++  java
  • Python 赋值、浅拷贝和深拷贝

    初学Python,和C++还是有许多不同。直接赋值、浅拷贝和深拷贝,这三种拷贝对象的操作之间还是有许多的区别。Python语言的版本为2.7,在Pycharm中进行实验。

    一、直接赋值

    用下面的代码来实验:

     1 origin = [1, "string", [1, 3, 5]]
     2 Copy = origin
     3 print Copy
     4 print id(origin), id(Copy)
     5 Copy[0] = 5
     6 print origin, Copy
     7 Copy[1] = "changed"
     8 print origin, Copy
     9 Copy[2][0] = 111
    10 print origin, Copy
    11 print id(origin), id(Copy)

    运行的结果如下:

    [1, 'string', [1, 3, 5]]
    38994824 38994824
    [5, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]]
    [5, 'changed', [1, 3, 5]] [5, 'changed', [1, 3, 5]]
    [5, 'changed', [111, 3, 5]] [5, 'changed', [111, 3, 5]]
    38994824 38994824

    可见,直接赋值的新变量完完全全就是一个原对象的引用,任何对复制对象的引用都会影响到原对象。

    二、浅拷贝

    用相同的代码来测试,仅仅把拷贝方式改成了copy.copy():

     1 import copy
     2 origin = [1, "string", [1, 3, 5]]
     3 Copy = copy.copy(origin)
     4 print Copy
     5 print id(origin), id(Copy)
     6 Copy[0] = 5
     7 print origin, Copy
     8 Copy[1] = "changed"
     9 print origin, Copy
    10 Copy[2][0] = 111
    11 print origin, Copy
    12 print id(origin), id(Copy)

    运行的结果如下:

    [1, 'string', [1, 3, 5]]
    39453768 39510280
    [1, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]]
    [1, 'string', [1, 3, 5]] [5, 'changed', [1, 3, 5]]
    [1, 'string', [111, 3, 5]] [5, 'changed', [111, 3, 5]]
    39453768 39510280

    这次可以发现,两个对象指向的内存并不相同,也就是说,浅拷贝的对象是一个新的对象。另外,可以发现,对新对象的元素进行替换并不会影响到原对象,而对子对象——列表的修改会影响到原对象。

    三、深拷贝

    同样,只是把拷贝方式换成copy.deepcopy():

     1 import copy
     2 origin = [1, "string", [1, 3, 5]]
     3 Copy = copy.deepcopy(origin)
     4 print Copy
     5 print id(origin), id(Copy)
     6 Copy[0] = 5
     7 print origin, Copy
     8 Copy[1] = "changed"
     9 print origin, Copy
    10 Copy[2][0] = 111
    11 print origin, Copy
    12 print id(origin), id(Copy)

    结果如下:

    [1, 'string', [1, 3, 5]]
    39978056 39994504
    [1, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]]
    [1, 'string', [1, 3, 5]] [5, 'changed', [1, 3, 5]]
    [1, 'string', [1, 3, 5]] [5, 'changed', [111, 3, 5]]
    39978056 39994504

    同样,两个对象指向的内存位置并不相同,说明创建了新对象。此外,新对象的任何改动都不影响到原有的对象。

    结论:

    (1)直接赋值是一个完完全全的引用,对新变量的任何改动都会影响到原对象。

    (2)浅拷贝创建了新的对象,但是只拷贝了序列的元素,对于元素也是一个序列的情况(即子对象),只复制了对这个序列的引用!

    (3)深拷贝是完完全全的拷贝,把原对象完整地拷贝到了新对象中。

  • 相关阅读:
    4、提取看似无用的委托变量,减少构造开销
    Cloud Foundry buildpack
    mysql中engine=innodb和engine=myisam的区别
    Maven中dependencyManagement的作用
    bean
    servlet
    web服务器 应用服务器区别 web框架
    Java和Python的Web开发
    spring mvc controller 高并发问题
    es 批量添加数据
  • 原文地址:https://www.cnblogs.com/lustar/p/8372636.html
Copyright © 2011-2022 走看看