赋值

python跟java中的变量本质是不一样的,Python的变量实质上是一个指针(int型或str型),而java的变量是一个可操作的存储空间。

  1. a = 123
    b = a
  2.  
  3. print(id(a))
    print(id(b))
  4.  
  5. print(a is b)
  6.  
  7. result

  26848576
  26848576
  True

这里可以看到a和b的地址是一样的,a=123,实质上是将a这个对象"贴到"123上;同样,b=a,也是将b这个对象“贴到”123上,这里变量实际上是个“便利贴“。

下面用一个可变的对象list来做说明:

  1. a = [1, 2, 3]
  2. b = a
  3.  
  4. a.append(4)
  5. a[0] = 6
  6. print(a)
  7. print(b)
  8.  
  9. result:
  10. [6, 2, 3, 4]
  11. [6, 2, 3, 4]

首先把a和b贴在 [1,2,3]这个对象上,然后通过append,[1,2,3]这个对象变成了[1,2,3,4],再通过a[0]=6,将对象[1,2,3,4]的第0个元素地址对应值改为6,

则最终这个对象是[6,2,3,4],然而a和b仍然是贴在这个对象上的,即a和b都是[6,2,3,4]

浅拷贝(copy)

对于浅拷贝有两种情况:

1. 浅拷贝值是不可变对象(数值,字符串,元组)时,等同于赋值,对象的id值与浅拷贝原来的值相同。

  1. import copy
  2.  
  3. a = 1
  4. b = a
  5. c = copy.copy(a)
  6.  
  7. print(id(a))
  8. print(id(b))
  9. print(id(c))
  10.  
  11. result:
  12. 35258712
  13. 35258712
  14. 35258712

2. 浅拷贝值是可变对象(list,dict)时:

2.1 不包含子对象

  1. # coding:utf-8
  2. import copy
  3.  
  4. a = [1, 2, 3]
  5. b = a
  6. c = copy.copy(a)
  7. print("append前c={}".format(id(c)))
  8. a.append(4)
  9.  
  10. print("a={}".format(id(a)))
  11. print("b={}".format(id(b)))
  12. print("append后c={}".format(id(c)))
  13.  
  14. print("a值={}".format(a))
  15. print("b值={}".format(b))
  16. print("c值={}".format(c))
  17.  
  18. result:
  19. appendc=139982846485352
  20. a=139982846912272
  21. b=139982846912272
  22. appendc=139982846485352
  23. a值=[1, 2, 3, 4]
  24. b值=[1, 2, 3, 4]
  25. c值=[1, 2, 3]

对于不包含子对象的情况下,原值的改变并不会影响浅拷贝的值,同时浅复制的值改变也并不会影响原值,并且浅拷贝是新开辟的一块内存,与原对象内存地址不同。

2.2 包含子对象

  1. # coding:utf-8
  2. import copy
  3.  
  4. a = [1, [4], 2, 3]
  5. b = a
  6. c = copy.copy(a)
  7. print("append前c={}".format(id(c)))
  8. a.append(5)
  9. a[1].append(9)
  10.  
  11. print("a={}".format(id(a)))
  12. print("b={}".format(id(b)))
  13. print("append后c={}".format(id(c)))
  14.  
  15. print("a值={}".format(a))
  16. print("b值={}".format(b))
  17. print("c值={}".format(c))
  18.  
  19. result:
  20. appendc=140519703466856
  21. a=140519703889752
  22. b=140519703889752
  23. appendc=140519703466856
  24. a值=[1, [4, 9], 2, 3, 5]
  25. b值=[1, [4, 9], 2, 3, 5]
  26. c值=[1, [4, 9], 2, 3]

可以看出,浅拷贝只拷贝父对象([1,2,3]),不会拷贝对象内部的子对象([4]),改变原对象中复杂子对象的值时会改变浅拷贝的值。

深拷贝(deepcopy)

  1. # coding:utf-8
  2. import copy
  3.  
  4. a = [1, [4], 2, 3]
  5. print("a原始值={}".format(a))
  6. b = a
  7. d = copy.deepcopy(a)
  8.  
  9. a.append(5)
  10. a[1].append(9)
  11.  
  12. print("a={}".format(id(a)))
  13. print("b={}".format(id(b)))
  14. print("d={}".format(id(d)))
  15.  
  16. print("a值={}".format(a))
  17. print("b值={}".format(b))
  18. print("d值={}".format(d))
  19.  
  20. result:
  21. a原始值=[1, [4], 2, 3]
  22. a=139675956164440
  23. b=139675956164440
  24. d=139675955741904
  25. a值=[1, [4, 9], 2, 3, 5]
  26. b值=[1, [4, 9], 2, 3, 5]
  27. d值=[1, [4], 2, 3]

深拷贝则会拷贝对象及其子对象,深拷贝的时候会将复杂对象的每一层复制一个单独的个体出来,原对象的值改变时并不会影响deepcopy的值,

但是,由于深拷贝需要维护一个 内存 用于记录已经拷贝的对象,所以深拷贝的速度会比较慢。

深入理解Python中赋值、深拷贝(deepcopy)、浅拷贝(copy)的更多相关文章

  1. **Python中的深拷贝和浅拷贝详解

    Python中的深拷贝和浅拷贝详解   这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容.   要说清楚Python中的深浅拷贝,需要 ...

  2. 001 说说Python中的深拷贝和浅拷贝

    在Python编程中忽略深拷贝和浅拷贝可能会造成未知的风险. 比如我们打算保存一份原始对象的副本作为上一状态的记录,此后修改原始对象数据时,若是副本对象的数据也发生改变,那么这就是一个严重的错误. 注 ...

  3. python中的深拷贝和浅拷贝理解

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用.以下分两个思路来分别理解浅拷贝和深拷贝: 利用切 ...

  4. python中的深拷贝与浅拷贝

    深拷贝和浅拷贝 浅拷贝的时候,修改原来的对象,浅拷贝的对象不会发生改变. 1.对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷 ...

  5. python中的深拷贝和浅拷贝

    python的复制,深拷贝和浅拷贝的区别   在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一 ...

  6. 低门槛彻底理解JavaScript中的深拷贝和浅拷贝

    作者 | 吴胜斌 来源 | https://www.simbawu.com/article/search/9 在说深拷贝与浅拷贝前,我们先看两个简单的案例: //案例1var num1 = 1, nu ...

  7. 理解JavaScript中的深拷贝和浅拷贝

    , num2 = num1;console.log(num1) //1console.log(num2) //1num2 = 2; //修改num2console.log(num1) //1conso ...

  8. Python 中的深拷贝和浅拷贝

    一.浅拷贝python中 对象赋值时 默认是浅拷贝,满足如下规律:1. 对于 不可变对象(字符串,元组 等),赋值 实际上是创建一个新的对象:例如: >>> person=['nam ...

  9. python中的深拷贝和浅拷贝(面试题二)

    一.浅拷贝 定义:浅拷贝只是对另外一个变量的内存地址的拷贝,这两个变量指向同一个内存地址的变量值. 浅拷贝的特点: 公用一个值: 这两个变量的内存地址一样: 对其中一个变量的值改变,另外一个变量的值也 ...

随机推荐

  1. 图解elasticsearch的_source、_all、store和index

    Elasticsearch中有几个关键属性容易混淆,很多人搞不清楚_source字段里存储的是什么?store属性的true或false和_source字段有什么关系?store属性设置为true和_ ...

  2. 洛谷P5219 无聊的水题 I [prufer序列,生成函数,NTT]

    传送门 思路 有标号无根树的计数,还和度数有关,显然可以想到prufer序列. 问题就等价于求长度为\(n-2\),值域为\([1,n]\),出现次数最多的恰好出现\(m-1\)次,这样的序列有哪些. ...

  3. jenkins 安装网址

    https://wiki.jenkins.io/display/JENKINS/Installing+Jenkins

  4. Struts2中类数据封装的方式

    第一种方式:属性驱动提供对应属性的set方法进行数据的封装.表单的哪些属性需要封装数据,那么在对应的Action类中提供该属性的set方法即可.表单中的数据提交,最终找到Action类中的setXxx ...

  5. yum -y 与yum有何区别(转载)

    在linux中,经常使用yum来进行软件的安装,更新与卸载,那我们会发现,在使用yum的时候,通常有下面两种指令模式:    ①yum install  xxx     ②yum -y install ...

  6. 各数据库连接maven配置

    Derbydb driver maven dependency<dependency> <groupId>org.apache.derby</groupId> &l ...

  7. 1,环境的搭建,angular

    也是学习一些皮毛,只是把这些经验记录下来而已. 至于angular有什么好处,或者有什么是什么,我就不多做介绍,自己可以去百度,肯定能找到更为详细的. 我使用的是google提供的angualr-cl ...

  8. selenium 操作键盘

    send_keys(Keys.ENTER) 按下回车键send_keys(Keys.TAB) 按下Tab制表键send_keys(Keys.SPACE) 按下空格键spacesend_keys(Kye ...

  9. jenkins 回滚发布

    #jenkins拉取文件路径 workspace=/data/wos/testtemp #备份路径 backspace=/data/wos/back #不能提Git的文件 config=/data/w ...

  10. C++ Primer 笔记——类成员指针

    1.当我们初始化一个成员指针或为成员指针赋值时,该指针并没有指向任何数据.成员指针指定了成员而非成员所属的对象,只有当解引用成员指针时,我们才提供对象信息. 2.和普通的函数指针类似,如果成员存在重载 ...