python中有一个模块copy,deepcopy函数用于深拷贝,copy函数用于浅拷贝。

要理解浅拷贝,必须先弄清楚python中的引用。

引用

Python中一切都是对象,变量中存放的是对象的引用

这是一个普遍的法则。能够说
Python 没有赋值,仅仅有引用

如。a=1,变量a仅仅是整数对象1的引用。

可变对象与不可变对象及其引用

一、不可变对象

不可变对象包含:数字,字符串,元组。
因为Python中的变量存放的是对象引用。所以对于不可变对象而言,虽然对象本身不可变。但变量的对象引用是可变的。运用这种机制,有时候会让人产生糊涂,似乎可变对象变化了。如以下的代码:
i=73
i+=2

这里的‘=’表示引用。



从上面得知。不可变的对象的特征没有变,依旧是不可变对象,变的仅仅是创建了新对象,改变了变量的对象引用。

二、可变对象

可变对象包含:列表、字典
其对象的内容是能够变化的。

当对象的内容发生变化时。变量的对象引用是不会变化的。如以下的样例。

m=[5,9]
m+=[6]

列表m的每一个元素均是对象的引用。对象的生成。涉及到相应机制。如整形对象分为大整数对象和小整数对象,生成机制不同,这里不作具体阐述。


三、函数的參数传递

函数的參数传递。本质上传递的是引用。

拷贝

(1)没有限制条件的分片表达式(L[:])可以复制序列,但此法仅仅能浅层复制。

(2)字典 copy 方法。D.copy() 可以复制字典,但此法仅仅能浅层复制

(3)有些内置函数。比如 list,可以生成拷贝 list(L)

(4)copy 标准库模块可以生成完整拷贝:deepcopy,递归 copy

浅拷贝

浅拷贝由copy模块中的copy()函数实现。简单地说,copy.copy 浅拷贝 仅仅拷贝父对象,不会拷贝对象的内部的可变子对象。

详细点说就是。浅拷贝是指拷贝的仅仅是原对象元素的引用,换句话说,浅拷贝产生的对象本身是新的,可是它的内容不是新的,仅仅是对原子对象的一个引用。



import copy
aList=[[1,2],3,4]
bList=copy.copy(aList)
print aList
print bList print id(aList)
print id(bList) aList[0][0]=5 print aList
print bList

由id(aList)不等于id(bList),表明浅拷贝产生的对象本身是新的。可是它的子对象(即,那个列表)是对原子对象的一个引用。

那么3,4两个元素呢?这就要讲讲python中的可变对象和不可变对象的引用了。



可是有点须要特别提醒的,假设对象本身是不可变的,那么浅拷贝时也是引用。

见这个样例:

import copy
aList=[[1,2],3,4]
bList=copy.copy(aList)
print aList
print bList print id(aList[1])
print id(bList[1]) aList[2]=5#变量的对象引用改变了而已
aList[0]=[0,1,1]#变量的对象引用改变了而已 print aList
print bList

总结,即浅拷贝产生的对象本身是新的。可是它的内容不是新的,仅仅是对原子对象的一个引用。

深拷贝

浅拷贝由copy模块中的deepcopy()函数实现,简单地说。深拷贝 拷贝对象及其子对象。

一个样例展示引用、深拷贝与浅拷贝的不同。

import copy
aList=[[1,2],3,4]
bList=aList
cList=copy.copy(aList)
dList=copy.deepcopy(aList)
print aList
print bList
print cList
print dList
print id(aList)
print id(bList)
print id(cList)
print id(dList)
aList.append(5)
aList[0].append('hello') print aList
print bList
print cList
print dList


事实上我认为记住这一点即可,浅拷贝产生的对象本身是新的,可是它的内容不是新的。仅仅是对原子对象的一个引用。关键是要理解python中引用的含义。




一入python深似海--浅拷贝与深拷贝的更多相关文章

  1. 一入python深似海--dict(字典)的一种实现

    以下是python中字典的一种实现.用list数据结构实现字典.详细是这种:[[(key1,value1),(key2,value2),...],[],[],...] 内部每个hash地址是一个lis ...

  2. 一入python深似海--class

    python class 分为三个部分:class and object(类与对象),inheritance(继承),overload(重载)and override(覆写). class and o ...

  3. 一入python深似海--变量和对象

    一.基本原理 Python中一切都是对象,变量是对象的引用. 这是一个普遍的法则.我们举个样例来说.Python是怎样来处理的. x = 'blue' y = 'green' z = x 当pytho ...

  4. 一入python深似海--range()、list与for

    range使用方法 使用python的人都知道range()函数非常方便,今天再用到他的时候发现了非常多曾经看到过可是忘记的细节. 这里记录一下: range(1,5)#代表从1到5(不包括5) [1 ...

  5. 一入python深似海--python之道

    python社区不乏幽默.先来看"python之道"这首诗. 导入this包: import this 输出是一首诗,这首诗总结了Python的风格,能够指导Python程序猿的编 ...

  6. 一入python深似海--对象的属性

    Python中一切皆是对象,每一个对象都能够有多个属性.Python是怎样管理这些属性呢?我们来探讨一下. 属性的__dict__系统 对象的属性包括两部分:类属性和对象属性.对象的属性可能来自于其类 ...

  7. 一入Python深似海--print

    先给大家来个干货^~^,学习Python的一个好站点,http://learnpythonthehardway.org/book/ 经典样例 以下是几个老经典的样例喽,刚接触Python的能够敲一敲, ...

  8. 「一入 Java 深似海 」系列课程

    第一期 「一入 Java 深似海 」系列课程 - 第一期 第一节:Java 语言基础

  9. 一入爬虫深似海,从此游戏是路人!总结我的python爬虫学习笔记!

    前言 还记得是大学2年级的时候,偶然之间看到了学长在学习python:我就坐在旁边看他敲着代码,感觉很好奇.感觉很酷,从那之后,我就想和学长一样的厉害,就想让学长教我,请他吃了一周的饭,他答应了.从此 ...

随机推荐

  1. 【Tomcat】使用Eclipse发布项目时,项目启动路径错误。

    这种情况下,,通常会去C:\User\[USERNAME]\或者Tomcat路径下面的一个temp文件夹里面找项目文件,由此出现报错. 这时候解决方法为: 双击Eclipse的Servers里面的to ...

  2. 浅谈JSP(二)

    一.EL表达式 作用:从作用域(pageContext,request,session,application)中取值,并显示在页面中. 本质:用于替换输出脚本(<%= %>). 1.从作 ...

  3. C++中 指针 与 引用 的区别

    四点区别:可否为空,可否修改,使用时是否需要判断,使用场景 非空区别. 引用必须指向某个对象,而指针可以指向空. 可修改区别. 引用总是与初始化时的那个对象绑定,不可变更:指针可以重新赋值,指向另外一 ...

  4. .net Web应用程序使用IIS调试

    1.这种调试方式是区别于使用Visual Studio 自带的调试方式 2.点击[创建虚拟目录],成功

  5. A Byte of Python 笔记(6)模块

    第8章 模块 用户在程序中定义一次函数而重用代码,如果用户想在其他程序中重用很多函数,可以通过使用模块的方式. 模块就是一个包含了所有用户定义的函数和变量的文件.为了在其他程序中重用模块,模块的文件名 ...

  6. JAVA堆与栈

    数据类型: Java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本身 ...

  7. Angulajs 定时器使用

    在Angulajs的control中,不能利用 window.setInterval和 setTimeout 来操作定时器,因为这样做,虽然设置定时器会成功,但对$scope中的数据进行设置时,不会自 ...

  8. 再探java基础——break和continue的用法

    再探java基础——break和continue的用法 break break可用于循环和switch...case...语句中. 用于switch...case中: 执行完满足case条件的内容内后 ...

  9. robomongo

    Robomongo 是一个可视化的mongodb数据库工具,提供对mongodb的操作,javascript执行及语法高亮提示. 安装教程

  10. linux 进程间信号量管理程序之sem_timedwait使用

    在开发过程中,有三个独立执行的程序模块,三个模块都对sqlite数据库进行读写操作.sqlite在linux共享性较差,所以须要增加相互排斥信号量解决三个模块訪问数据库该问题. 另外,在增加信号量后, ...