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中引用的含义。