python变量、引用、拷贝之间的关系
2017-05-09 16:18
337 查看
Python中一切皆为对象,不管是集合变量还是数值型or字符串型的变量都是一个引用,都指向对应内存空间中的对象。
简而言之:变量直接赋值:新变量本身及其内部的元素都与原变量指向相同的内存空间,并且值相同,当一个发生变化时,另一个也随之变化。
变量浅拷贝:新变量本身与原变量指向不同的内存空间,但是新变量内部的元素与原变量指向相同的内存空间;当改变原变量内部的可变对象的值时,新变量内部的值也发生随之变化;改变原变量内部的不可变对象的值时,新变量内部的值不随之变化;反之亦然(即改变新变量时)。
变量深拷贝:新变量与原变量本身及其内部元素都指向不同的内存空间,改变原变量的值时,新变量中的值不会发生变化,反之亦然。
1. 不可变对象:int,float,long,str,tuple等;
1 In[20]: a = 1 2 In[21]: b = a 3 In[22]: id(a) 4 Out[22]: 33719592L 5 In[23]: id(b) 6 Out[23]: 33719592L 7 In[24]: a = 2 8 In[25]: id(a) 9 Out[25]: 33719568L 10 In[26]: id(b) 11 Out[26]: 33719592L 12 In[27]: b = 3 13 In[28]: id(b) 14 Out[28]: 33719544L
可以看出最开始a、b指向同一个内存空间,但是当改变a的值时,a指向了新的内存空间(此时b没有发生变化),改变b时b也指向了新的内存空间;类似于C语言中的值传递。
2. 可变对象:list,set,dict, array, matrix等
1 In[29]: list1 = [1,2,3] 2 In[30]: list2 = list1 3 In[31]: id(list1) 4 Out[31]: 61244552L 5 In[32]: id(list2) 6 Out[32]: 61244552L 7 In[33]: list1[0] = 101 8 In[34]: id(list1) 9 Out[34]: 61244552L 10 In[35]: id(list2) 11 Out[35]: 61244552L 12 In[36]: list1 13 Out[36]: [101, 2, 3] 14 In[37]: list2 15 Out[37]: [101, 2, 3] 16 In[38]: list2[1] = 102 17 In[39]: id(list1) 18 Out[39]: 61244552L 19 In[40]: id(list2) 20 Out[40]: 61244552L 21 In[41]: list1 22 Out[41]: [101, 102, 3] 23 In[42]: list2 24 Out[42]: [101, 102, 3]
刚开始list1和list2指向同一个内存空间,改变list1中的值时,list2也跟着改变,但是它们指向的内存空间没有发生变化;同样,改变list2中的值时,list1的值也跟着变化,它们仍然指向同一个内存空间。
浅拷贝和深拷贝:
下述例子中:b和a指向同一个内存空间,改变a中的值,则b跟着改变。c是a浅拷贝,c指向和a不同的内存空间,但是如果a中有一个元素为可变对象,则c中的此元素和a中的元素指向同一个内存空间,则改变a中此可变对象里面的值时,c中的值也改变;改变a中不可变对象的元素的值时,c中的值不发生变化。d是a的深拷贝,d和a指向不同的内存空间,d内部的元素和a内部元素也指向不同的空间,改变a里面的值时,d不会发生变化。
例子说明:
1 import copy 2 a = [1,[1, 2, 3], [4, 5, 6]] 3 b = a 4 c = copy.copy(a) 5 d = copy.deepcopy(a) 7 a.append(15) 8 a[1][2] = 10 9 a[0] = 0 11 print a 12 print b 13 print c 14 print d 16 print id(a) 17 print id(b) 18 print id(c) 19 print id(d) 输出
1 [0, [1, 2, 10], [4, 5, 6]] 2 [0, [1, 2, 10], [4, 5, 6]] 3 [1, [1, 2, 10], [4, 5, 6]] 4 [1, [1, 2, 3], [4, 5, 6]] 5 38023496 6 38023496 7 36700104 8 38023368 再如
1 print 'a[1]',id(a[1]) 2 print 'b[1]',id(b[1]) 3 print 'c[1]',id(c[1]) 4 print 'd[1]',id(d[1]),'\n' 6 print 'a[0]',id(a[0]) 7 print 'b[0]',id(b[0]) 8 print 'c[0]',id(c[0]) 9 print 'd[0]',id(d[0]) 输出
1 a[1] 39654856 2 b[1] 39654856 3 c[1] 39654856 4 d[1] 39704904 6 a[0] 34112864 7 b[0] 34112864 8 c[0] 34112834 9 d[0] 34112840
简而言之:
变量直接赋值:新变量本身及其内部的元素都与原变量指向相同的内存空间,并且值相同,当一个发生变化时,另一个也随之变化。
变量浅拷贝:新变量本身与原变量指向不同的内存空间,但是新变量内部的元素与原变量指向相同的内存空间;当改变原变量内部的可变对象的值时,新变量内部的值也发生随之变化;改变原变量内部的不可变对象的值时,新变量内部的值不随之变化;反之亦然(即改变新变量时)。
变量深拷贝:新变量与原变量本身及其内部元素都指向不同的内存空间,改变原变量的值时,新变量中的值不会发生变化,反之亦然。
参考:http://blog.csdn.net/u013573813/article/details/53349798
相关文章推荐
- python变量、引用、拷贝之间的关系
- C++ 指针,引用,普通变量之间的关系
- python对象、引用、全局变量和局部变量的关系
- 04 Python正则表达式 爬虫程序 变量的引用,浅拷贝,深拷贝 多线程 进程锁 数据库模块
- Python中的变量、引用、拷贝和作用域
- Python中变量赋值传递时的引用和拷贝
- Python中模块之间变量引用的方法说明
- Python中的变量、引用、拷贝和作用域
- python变量的拷贝与引用
- Python中实现变量赋值传递时的引用和拷贝方法
- Python中模块之间变量引用的方法说明
- python学习(九)python中的变量、引用和对象的关系
- Python中模块之间变量引用的方法说明
- 解析Python中的变量、引用、拷贝和作用域的问题
- Python全局变量在模块之间引用的问题
- [python] 解析源码中的structs,并建立它们之间的引用关系
- 第2章 Java编程基础——FAQ2.14 变量之间传值时可分为值传递和引用传递, 那么它们有何区别?
- Python实现在不同Linux主机之间拷贝文件
- .net DLL之间是通过AssemblyVersion建立引用关系的
- Python中变量传递时的引用和赋值