Python Copy:

在Python语言中,分为浅拷贝和深拷贝两种形式,也就是官方文档中的Shadow copy和Deep copy。在对简单的对象(object)进行复制时,两者没有区别,如下面的代码所示:

 #简单对象的浅copy和深copy对比
import copy
list1 = [1,2,3,4,5]
#浅复制
Shadow_copy_list1 = copy.copy(list1)
print(list1) #[1, 2, 3, 4, 5]
print(Shadow_copy_list1) #[1, 2, 3, 4, 5]
#对原对象元素进行修改:列表末尾添加'6'
list1.append(6)
print(list1) #[1, 2, 3, 4, 5, 6]
print(Shadow_copy_list1) #[1, 2, 3, 4, 5]
print(id(list1)) #地址:
print(id(Shadow_copy_list1)) #地址: #深复制
Deep_copy_list1 = copy.deepcopy(list1)
print(list1) #[1, 2, 3, 4, 5]
print(Deep_copy_list1) #[1, 2, 3, 4, 5]
#对原对象元素进行修改:列表末尾添加'6'
list1.append(6)
print(list1) #[1, 2, 3, 4, 5, 6]
print(Deep_copy_list1) #[1, 2, 3, 4, 5] print(id(list1)) #地址:
print(id(Deep_copy_list1)) #地址:

从简单对象的浅copy和深copy可以看出,对原列表中的元素进行修改,copy的对象里面的元素不会发生改变。

对于浅copy和深copy,在复杂对象的copy中会有所区别,如下程序所示:

 #复杂对象的浅copy和深copy对比
import copy
list1 = [1,2,3,[4,5]]
#浅copy
Shadow_copy_list1 = copy.copy(list1)
list1[3][0] = 7
print(list1) #[1, 2, 3, [7, 5]]
print(Shadow_copy_list1) #[1, 2, 3, [7, 5]]
print(id(list1)) #地址:
print(id(Shadow_copy_list1)) #地址: list1[3][0] = 4 #将列表恢复为初始列表
#深copy
Deep_copy_list1 = copy.deepcopy(list1)
list1[3][0] = 7
print(list1) #[1, 2, 3, [7, 5]]
print(Deep_copy_list1) #[1, 2, 3, [4, 5]]
print(id(list1)) #地址:
print(id(Deep_copy_list1)) #地址:

从复杂对象的浅copy和深copy可以看出,当浅copy时,如果对复杂对象的子对象元素进行修改,原列表和copy的列表里面的子对象元素都会产生变化,但是当深copy时,若复杂对象的子对象元素发生了变化,copy的对象的所有元素都不会发生变化。这是什么原因呢,这是因为浅拷贝只复制一层对象的属性,而深复制则递归复制了所有层级。

1、copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。

2、copy.deepcopy 深拷贝 拷贝对象及其子对象

(深copy)

深copy新建一个对象重新分配内存地址,在内存中生成完全一模一样的内容。

(浅copy)

浅copy也会对复制后的列表重新分配内存地址。但是在浅copy中,对于列表里面的元素,浅copy复制的是元素的内存地址,相当于引用,此时的子对象属于公共对象,浅copy如果对象中有引用其他的对象,如果对这个子对象进行修改,子对象的内容就会发生更改。

总结:

  1. 在简单对象中,无论是浅copy还是深copy,原对象里面元素的变化不会引起复制对象里面的元素的变化。
  2. 在复杂对象中,原对象的子对象元素发生变化,浅copy的对象里面的子对象元素也会产生变化,此时该子对象相当于镜像文件,对于引用它的对象,都会产生影响,而在深copy中,由于深copy是对所有的元素进行了复制,所以原对象里面子对象元素的变化不会导致复制对象里面元素的变化。

Python 赋值:

简单对象的赋值、浅copy和深copy对比:

 #简单对象的赋值、浅copy和深copy对比
import copy
list1 = [1,2,3,4,5]
New_list1 = list1
Shadow_copy_list1 = copy.copy(list1)
Deep_copy_list1 = copy.deepcopy(list1)
#对原对象元素进行修改:列表末尾添加'6'
list1.append(6)
#原列表
print(list1) #[1, 2, 3, 4, 5, 6]
print(id(list1)) #地址:1913255661704
#赋值列表
print(New_list1) #[1, 2, 3, 4, 5, 6]
print(id(New_list1)) #地址:1913255661704
#浅copy列表
print(Shadow_copy_list1) #[1, 2, 3, 4, 5]
print(id(Shadow_copy_list1)) #地址:1913255661896
#深copy列表
print(Deep_copy_list1) #[1, 2, 3, 4, 5]
print(id(Deep_copy_list1)) #地址:1913255663176

从程序运行结果可以看出,简单对象中,若原列表元素发生改变,则通过赋值的新列表元素也会改变,而浅copy和深copy的列表元素均不会发生变化。可以认为赋值是将原对象上贴上两个标签,如程序中的list1标签和New_list1两个标签,使用的也是内存中的同一块地址,列表中元素的变化,则两个list均会产生变化。而使用copy进行复制的则不同了,不管是浅copy和深copy,都会重新在内存中分配一块地址,这样原列表中元素的变化,复制的列表中不会产生变化。

复杂对象的赋值、浅copy和深copy对比:

 #复杂对象的赋值、浅copy和深copy对比
import copy
list1 = [1,2,3,[4,5]]
New_list1 = list1
Shadow_copy_list1 = copy.copy(list1)
Deep_copy_list1 = copy.deepcopy(list1)
#对原对象元素进行修改:将列表中第4个元素中的'4'更改为'7'
list1[3][0] = 7
#原列表
print(list1) #[1, 2, 3, [7, 5]]
print(id(list1)) #地址:1975516434760
#赋值列表
print(New_list1) #[1, 2, 3, [7, 5]]
print(id(New_list1)) #地址:1975516434760
#浅copy列表
print(Shadow_copy_list1) #[1, 2, 3, [7, 5]]
print(id(Shadow_copy_list1)) #地址:1975516436040
#深copy列表
print(Deep_copy_list1) #[1, 2, 3, [4, 5]]
print(id(Deep_copy_list1)) #地址:1975516435976

从程序运行结果可以看出,对复杂对象的子对象元素进行修改时,通过赋值的列表与浅copy的列表中的子对象也会随之改变,因为此时复杂对象中的子对象作为公共对象,浅copy时,新的列表还是引用的原列表中的子对象。而深copy则不一样,深copy是进行递归复制的,将列表的所有层都进行了复制,所以原列表中子对象元素的变化不会导致深copy的列表中的子对象的变化。

初学者,如有分析的不正确的地方,欢迎交流讨论。

Python学习-赋值、浅copy和深copy的更多相关文章

  1. python学习笔记-(六)深copy&浅copy

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用. 1. 赋值 赋值其实只是传递对象引用,引用对象 ...

  2. python浅copy和深copy

    import   copy person =["name",[count,3000]] husband=copy.copy(person) wife=copy.copy(perso ...

  3. 浅copy 与 深copy

    import copy names = ["zhangyang", 'guyun', 'xiangpeng', ['jack','tom'], 'xuliangchen'] nam ...

  4. 【ObjectC—浅copy和深copy】

    一.OC设计copy的目的 为了能够从源对象copy一个新的对象副本,改变新对象(副本)的时候,不会影响到原来的对象. 二.实现copy协议 OC提供了两种copy方法:copy和mutableCop ...

  5. 浅copy与深copy举例

     例1: #!/usr/bin/env python import copy d1 = {'x':1,'y':2,'z':[3,4.5]} d2 = d1 d3 = d1.copy() d4 = co ...

  6. Python中的浅复制、深复制

    参考 https://docs.python.org/3/library/copy.html?highlight=copy%20copy#copy.copy https://en.wikipedia. ...

  7. java深copy (伪深copy)【原】

    Teacher.java package test.clone; /** * 老师 * 深copy需要实现Cloneable接口 * @author King * */ public class Te ...

  8. [Python]Python中的浅复制与深复制

    看python的文档,发现list有copy方法,描述说效果同a[:]. 感觉有点惊讶,之前一直以为a[:]执行的是深复制. test了一下,发现确实如果a中存在可变对象,如list/set/dict ...

  9. python学习(28) 浅谈可变对象的单例模式设计

    python开发,有时候需要设计单例模式保证操作的唯一性和安全性.理论上python语言底层实现和C/C++不同,python采取的是引用模式,当一个对象是可变对象,对其修改不会更改引用的指向,当一个 ...

随机推荐

  1. css 固定宽度,自动换行

    max-width: 200px; display: block; word-break: break-all:

  2. ContentControl和ContentPresenter的应用

    1:wpf中,所有的内容控件都继承自“ContentControl” ,所以我们可以直接应用“ContentControl”自定义我们“需要的”内容控件. 2:ContentControl具有Cont ...

  3. 微信小程序------联动选择器

    picker 从底部弹起的滚动选择器,现支持五种选择器,通过mode来区分,分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器. 先来看看效果图: 1:普通选择器 m ...

  4. 通用Mapper相关

    1.通用Mapper中,用@Table来映数据表与实体,其中 name:指定表的名称,例如@Table(name="ls_post") catalog: 指定数据库名称,默认为当前 ...

  5. opencv图像处理

    #coding=utf-8 import cv2 import numpy as np img1 = cv2.imread("3.jpg") img2 = cv2.imread(& ...

  6. windows使用pip安装selenium报错问题

    UnicodeDecodeError: 'ascii' codec can't decode byte 0xb9 in position 7: ordinal not in range(128) 这是 ...

  7. 八、dbms_rls(实现精细访问控制)

    1.概述 本报只适用于Oracle Enterprise Edition,它用于实现精细访问控制,并且精细访问控制是通过在SQL语句中动态增加谓词(WHERE子句)来实现的.通过使用ORACLE的精细 ...

  8. ZOJ 1609 Equivalence(状压+dfs减枝)

    ZOJ Problem Set - 1609 Equivalence Time Limit: 5 Seconds      Memory Limit: 32768 KB When learning m ...

  9. ZOJ 2975 Kinds of Fuwas(暴力+排列组合)

    Kinds of Fuwas Time Limit: 2 Seconds      Memory Limit: 65536 KB In the year 2008, the 29th Olympic ...

  10. SpringAnnotation注解之@Autowired

    @Autowired:自动装配,不用在bean里写<property>属性来指定所依赖的属性 1 2 3 4 @Autowired public void setUserDao(UserD ...