Python中的Copy和Deepcopy
一,Python的对象:
Python存在大量的对象,我们一般提到的对象都是C中的结构体在堆中申请的一块内存(以CPython为例),每一个对象都有ID,可以通过ID(Object)获得。对象的范围包括内建类型的对象(如int类型的对象123,str的对象"test",list的对象[],生成器对象等等)、用户自建类型的对象、函数(lambda函数,生成器函数)、类型、Ture、False(bool类型的对象)、None(NoneType的对象)。
print id(123)
print id("test")
print id([])
print id(xrange(1, 3))
print id(lambda v: v)
print id(int)
print id(True)
print id(None) print type(123)
print type("test")
print type([])
print type(xrange(1, 3))
print type(lambda v: v)
print type(int)
print type(True)
print type(None)
19257680
19062656
27888896
19590176
27863344
505361888
505379788
505354444
<type 'int'>
<type 'str'>
<type 'list'>
<type 'xrange'>
<type 'function'>
<type 'type'>
<type 'bool'>
<type 'NoneType'>
猜想int类型、True和None都是在高地址中,而动态生成的都是位于低地址中。
二,Python的引用计数:
所有对象都采用引用计数,给对象分配新名词或者将其放入容器中,这个对象的引用计数都会增加。当离开作用域或者被重新赋值的时候,这个对象的引用计数就会减少。当减少为0,垃圾收集器会将其销毁。
Python中的对象分为immutable和mutabel,作为immutable的int、char和tuple,相同的值在内存中只会生成一次,每次将其赋值到变量中,便会增加一个引用计数。而作为mutable的list、dict、xrange(生成器)和lambda(函数),每次生成都会在内存中生成一个新的对象。
另外:传参的时候,若参数为mutable,则传的是引用,若参数为immutable,则传的是值。
a = 123 #创建一个值为123的对象
b = 123 #增加123的引用计数
a = 111 #创建一个值为111的对象,减少123的引用计数
b = a #增加111的引用计数 c = [] #创建一个空队列
d = [] #创建一个新的空队列
c = [] #再创建一个新的空队列,减少原队列的引用计数
c = d #增加d队列的引用计数,减少c队列的引用计数
c.append(1) #创建一个值为1的对象,不改变原队列的引用计数
三,Shallow copy和Deep copy的区别
Python document中是这么说的:
- A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
- A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.
这其中的区别就是浅复制会简单的复制引用,不管他是mutable还是immutable。而深复制则会递归地复制immutable对象引用,对于mutable,则会新建一个对象。
import copy
a = [1, 2]
b = [a, 3]
c = copy.copy(b) #c = [[1, 2], 3]
d = copy.deepcopy(b) #d = [[1, 2], 3]
a.append(3) #c = [[1, 2, 3], 3]
#d = [[1, 2], 3]
四,如何控制Shallow copy和Deep copy?
在deepcopy时候,会遇到问题,比如有对象中有一个指向用户信息的列表,用户希望在复制的时候直接引用原列表。这个时候可以使用定制功能。
可以在类型中定义__copy__和__deepcopy__实现shallow copy和deep copy,当用户下次调用copy.copy和copy.deepcopy时,便会调用__copy__和__deepcopy__。
import copy
class Example(dict):
def __init__(self, needcopy={}, userinfo={}):
super(Example, self).__init__()
self.need = needcopy
self.user = userinfo def __deepcopy__(self, memo):
if memo is None:
memo = {}
result = self.__class__()
memo[id(self)] = result
for key in self.need.keys():
result.need = copy.deepcopy(self.need)
result.user = self.user
return result needcopy = {"price": 100}
userinfo = {"user": "vincent"}
a = Example(needcopy, userinfo)
b = copy.deepcopy(a)
needcopy["title"] = "no"
userinfo["passwd"] = "none"
print "need: ", a.need, "; user: ", a.user
print "need: ", b.need, "; user: ", b.user
need: {'price': 100, 'title': 'no'} ; user: {'passwd': 'none', 'user': 'vincent'}
need: {'price': 100} ; user: {'passwd': 'none', 'user': 'vincent'}
Output
Python中的Copy和Deepcopy的更多相关文章
- Python中=、copy、deepcopy
一.Python中的"=" a = 1 b = 1 c = a print(id(a)) print(id(b)) print(id(c)) #输出为 14070784103734 ...
- python中 =、copy、deepcopy的差别
python2中,需要import copy模块 python3中,直接可以使用copy()方法,但deepcopy()还是需要导入copy模块 下面以python2为例: 对于"=&quo ...
- copy模块中的copy与deepcopy的区别
前言 每空闲下来,就觉得以前写的博客很low........也许现在也很low~~~~好吧就当升级版的low吧~~~~ 如果要了解copy与deepcopy的区别,就需要了解Python的存储机制:P ...
- Python字典方法copy()和deepcopy()的区别
from copy import deepcopy # import deepcopy模块 d = {} d['name'] = ['black', 'guts'] # d = {'name': [' ...
- 深入理解Python中赋值、深拷贝(deepcopy)、浅拷贝(copy)
赋值 python跟java中的变量本质是不一样的,Python的变量实质上是一个指针(int型或str型),而java的变量是一个可操作的存储空间. a = 123b = a print(id(a) ...
- python中的copy.copy和copy.deepcopy
一个例子就搞清楚 import copy a = [1, 2, 3, 4, ['a', 'b']] #原始对象 b = a #赋值,传对象的引用 c = copy.copy(a) #对象拷贝,浅拷贝 ...
- python中深copy,浅copy
版权声明:本文为博主原创文章,未经博主允许不得转载. >>> mylist1 = [1, 2, 3, 4] >>> myl = mylist1 >>&g ...
- python中深copy,浅copy与赋值语句的区别
以下详细讲解:python深复制,浅复制与赋值语句的区别 1. '='赋值语句,常规复制只是将另一个变量名关联到了列表,并不进行副本复制,实例如下: var1=[12,35,67,91,101]var ...
- python copy与deepcopy (拷贝与深拷贝)
copy与deepcopy python 中的copy与deepcopy是内存数据的操作,但是两个函数有一定的区别. 1.copy import copy list = [1, [4, 5, 6], ...
随机推荐
- n!mod p的求法
我们假设p为素数,n!=a*pe,则我们需要求解a mod p和e. e是n!能够迭代整除p的次数,因此可以使用下面式子计算: n/p+n/p2+n/p3…… 我们只需要对pt≤n的t进行计算所以复杂 ...
- Qt中gb2312/GBK的URL编解码函数
编码函数: QByteArray encodeURI(QString str) { QByteArray array; QTextCodec *codec=QTextCodec::codecForNa ...
- Java中循环删除list中元素的方法总结
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后在今天使用的时候发现报错了,然后去科普了一下,发现这是一个误区.下面我们来一起看一下. Java中循环遍 ...
- Javascript兼容收集
1.IE6背景缓存 try{ document.execCommand("BackgroundImageCache", false, true); }catch(e){} 2. e ...
- dedecms友情链接flink的调用方法
标记名称:flink[标签简介][功能说明]:用于获取友情链接,其对应后台文件为"includetaglibflink.lib.php".[适用范围]:全局标记,适用V55,V56 ...
- Android原理View、ViewGroup
Android的UI界面都是由View和ViewGroup及其派生类组合而成的.其中,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的.Andro ...
- layout cannot be resolved or is not a field
去除代码activity代码页面顶部中的 import android.R;这句就可以消除红色波浪线的main cannot be resolved or is not a field类似这个错误了
- 自定义ScrollViewer的Touch事件--触摸上下移动ScrollViewer滚动到指定位置
double mPointY;//触摸点的Y坐标 double mOffsetY;//滚动条当前位置 bool mIsTouch = false;//是否触摸 //触摸事件 private void ...
- UVa 11401 三角形的个数
题意:由1,2,3...n组成的序列中找三个数,且以这三个数为变长能组成三角形,求这样的三角形个数. 思路:当每次输入n时重新都计算一遍会TLE...先预处理,将结果存入ans数组. 代码: #inc ...
- error Infos