python中的对象拷贝
python中。进行函数參数传递或者返回值时,假设是一般的变量,会拷贝传递。假设是列表或字典则是引用传递。那python怎样对列表和字典进行拷贝传递呢:标准库的copy模块提供了两个方法:copy和deepcopy方法。
1. copy.copy 浅拷贝 仅仅拷贝父对象,不会拷贝对象的内部的子对象。
2. copy.deepcopy 深拷贝 拷贝对象及其子对象
见下例:
import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始对象 e = a[:] #利用分片操作进行拷贝(浅拷贝)
b = a #赋值。传对象的引用
c = copy.copy(a) #对象拷贝,浅拷贝
d = copy.deepcopy(a) #对象拷贝,深拷贝 a.append(5) #改动对象a
a[4].append('c') #改动对象a中的['a', 'b']列表子对象 print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d
执行结果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c = [1, 2, 3, 4, ['a', 'b', 'c']]
d = [1, 2, 3, 4, ['a', 'b']]
e = [1, 2, 3, 4, ['a', 'b', 'c']]
分析:
b是a的一个引用。两者指向的对象同样,打印结果必定同样。c仅仅拷贝了a的中的父对象。对于a中嵌套的子对象列表并没有拷贝,所以c中的1,2,3,4是拷贝得到的副本,属于自己的,但嵌套的子对象列表还是a原来的。d的话,因为是深拷贝,所以子对象父对象都是拷贝生产的新的副本。全然不所原来a的影响。至于e,分片操作的效果等价于浅拷贝,结果和c同样。
以下以列表为例,看看函数參数传递和返回值中,是怎样进行引用传递的:
#coding=utf-8
def ggg():
l = [1, 2, 3] #局部变量
print 'local var ', l return l def fff(l):
l.append(100)
l[2].append('c') print "global var ", l #全局变量 return l a = ggg()
print a
a.append(10)
print a
ggg() print '\n\n' a = [1, 2, ['a', 'b'], 3]
b = fff(a)
print a
b.append(1000)
print b
print a
执行结果:
local var [1, 2, 3]
[1, 2, 3]
[1, 2, 3, 10]
local var [1, 2, 3]
global var [1, 2, ['a', 'b', 'c'], 3, 100]
[1, 2, ['a', 'b', 'c'], 3, 100]
[1, 2, ['a', 'b', 'c'], 3, 100, 1000]
[1, 2, ['a', 'b', 'c'], 3, 100, 1000]
分析:
a接受函数ggg返回的局部变量。但改动a后第二次调用函数ggg,ggg内的局部变量l并没有受到影响,课件ggg返回局部变量时是拷贝传递,就像C++中的一样:函数不可能返回局部变量的引用,由于局部变量保存在函数的栈空间中,函数调用结束后,栈被销毁。不能够对局部变量进行引用了。
将a传递给函数fff后。a被改变了。说明进行了引用传递;函数fff的返回值赋给b。对b的改动也会影响到a,说明返回值也是进行的引用传递(只是这里返回的可不是局部变量了)。
另外,字典还有自己的copy方法。但没有deepcopy方法。其copy方法和上面的copy模块中的copy方法一样,也是实现的浅拷贝。
另一点:对于一般变量,假设想达到引用传递的效果,怎么办呢?python标准库中并没有提供类似C++中专门的引用或指针的机制,要实现函数内部对传入变量的改动有两种途径:
1、通过函数返回值又一次赋值变量。
2、将变量封装在列表中在传给函数。
最后一点:把一个类的对象传递给函数的时候,类似引用传递,在函数内部改动类的变量。会真正改变其值。见下例:
class TestClass(object):
val1 = 100 #类变量 def __init__(self):
self.val2 = 200 #成员变量 def change(obj):
obj.val2 = 5555
obj.val1 = 6666 if __name__ == '__main__': inst0 = TestClass()
print '$$$ ',inst0.val1 #100
print '$$$ ',inst0.val2 #200 change(inst0) print '*** ',inst0.val1 #6666
print '*** ',inst0.val2 #5555
python中的对象拷贝的更多相关文章
- 【转】python中的对象拷贝
转自:https://www.cnblogs.com/bhlsheji/p/5352330.html python中.进行函数參数传递或者返回值时,假设是一般的变量,会拷贝传递.假设是列表或字典则是引 ...
- 天啦噜!仅仅5张图,彻底搞懂Python中的深浅拷贝
Python中的深浅拷贝 在讲深浅拷贝之前,我们先重温一下 is 和==的区别. 在判断对象是否相等比较的时候我们可以用is 和 == is:比较两个对象的引用是否相同,即 它们的id 是否一样 == ...
- Python 中的深浅拷贝
Python 中的深浅拷贝 参考文献:https://blog.csdn.net/lnotime/article/details/81194633 参考文献:https://blog.csdn.net ...
- Java 开发中的对象拷贝
前言 在 Java 开发中,很多时候需要将两个属性基本相同的对象进行属性复制,比如 DO 转 VO等等. 本文主要介绍自己实现的简易拷贝工具类与 Spring 提供的属性拷贝的对比. Spring 提 ...
- python中生成器对象和return 还有循环的区别
python中生成器对象和return 还有循环的区别 在python中存在这么一个关键字yield,这个关键字在项目中经常被用到,比如我写一个函数不想它只返回一次就结束那我们就不能用return,因 ...
- PyObject and PyTypeObject - Python 中的 '对象' 们
1 PyObject, PyTypeObject - Python 中的 '对象' 们 '一切皆对象' - 这是 Python 的学习和使用者们最最常听到一句, 可谓 博大精深 - '勃大精深'. ' ...
- Python中的深浅拷贝
1.什么是深浅拷贝? python中一切皆对象,python中的数字.字符串.元组等,如果存放在了内存中,这部分内存里面的内容是不会改变的,但是也有情况,内存中存放了可变对象,比如说列表和字典,他们的 ...
- Python中的深浅拷贝,赋值及引用
简单来说,若对象a中存的是列表或字典等可变对象,b对a的浅拷贝只是对对象第一层的复制,修改b第二层的元素仍然会影响两个对象. 深拷贝则是不会影响原来的对象. import copy.copy() 浅拷 ...
- Python基础【3】:Python中的深浅拷贝解析
深浅拷贝 在研究Python的深浅拷贝区别前需要先弄清楚以下的一些基础概念: 变量--引用--对象(可变对象,不可变对象) 切片(序列化对象)--拷贝(深拷贝,浅拷贝) 我是铺垫~ 一.[变量--引用 ...
随机推荐
- SDUT 1646 Complicated Expressions
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1646 题意 : 话说我根本没读题,,,因为实在 ...
- usb cdc 协议
什么是CDC类 (Communication Device Class) USB的CDC类是USB通信设备类 (Communication Device Class)的简称.CDC类是USB组织定义的 ...
- tbody添加垂直滚动条
法一: 用2个table: <table width="300" border="0" cellpadding="0" cellspa ...
- VIM 及其插件使用快捷键汇总
我的博客:www.while0.com vim搜索取消高亮 :nohl
- PLSQL操作
游标 SQL> set serveroutput onSQL> DECLARE 2 --定义游标,因为该游标中的数据需要更新,所以使用for update 3 CURSOR ...
- 【Python Network】权威域名服务器级联查询
如果PyDNS库,跳过本地名称服务器,直接向权威名称服务器查询.如baidu.com查询.com域名服务器,并从各个域名服务器中查询下一即域名,并输出相关信息. #! /usr/bin/env pyt ...
- 解决在IE里预览时弹出:为了有利于保护安全性......
用Dreamweaver做网页,在IE里预览时弹出这个:为了有利于保护安全性,Internet Explorer 已限制此网页运行可以访问计算机的脚本或ActiveX控件. 在页面顶部加段代码就可以了 ...
- BZOJ_3270_博物馆_(高斯消元+期望动态规划+矩阵)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3270 \(n\)个房间,刚开始两个人分别在\(a,b\),每分钟在第\(i\)个房间有\(p[ ...
- Apache Struts ClassLoader操作漏洞
漏洞版本: Apache Struts 2.x 漏洞描述: CVE ID:CVE-2014-0094 Struts2 是第二代基于Model-View-Controller (MVC)模型的java企 ...
- isIOS9
function isIOS9() { //获取固件版本 var getOsv = function () { var reg = /OS ((\d+_?){2,3})\s/; if (navigat ...