python变量、引用、拷贝之间的关系

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的值也跟着变化,它们仍然指向同一个内存空间。

浅拷贝和深拷贝:

 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 

b和a指向同一个内存空间,改变a中的值,则b跟着改变。c是a浅拷贝,c指向和a不同的内存空间,但是如果a中有一个元素为可变对象,则c中的此元素和a中的元素指向同一个内存空间,则改变a中此可变对象里面的值时,c中的值也改变改变a中不可变对象的元素的值时,c中的值不发生变化。d是a的深拷贝,d和a指向不同的内存空间,d内部的元素和a内部元素也指向不同的空间,改变a里面的值时,d不会发生变化

简而言之:

变量直接赋值:新变量本身及其内部的元素都与原变量指向相同的内存空间,并且值相同,当一个发生变化时,另一个也随之变化。

变量浅拷贝:新变量本身与原变量指向不同的内存空间,但是新变量内部的元素与原变量指向相同的内存空间;当改变原变量内部的可变对象的值时,新变量内部的值也发生随之变化;改变原变量内部的不可变对象的值时,新变量内部的值不随之变化;反之亦然(即改变新变量时)。

变量深拷贝:新变量与原变量本身及其内部元素都指向不同的内存空间,改变原变量的值时,新变量中的值不会发生变化,反之亦然。

参考:http://blog.csdn.net/u013573813/article/details/53349798

时间: 2024-12-09 20:31:46

python变量、引用、拷贝之间的关系的相关文章

python 变量引用

最近在看<<流畅的python>>关于变量引用部分时,有一些自己的看法,就再次记录一下. 问题: # From flunet python example 8-8 class Bus: def __init__(self, passengers=[]): self.passengers = passengers def pick(self, name): self.passengers,append(name) def remove(self, name): self.passen

Python学习笔记 | 变量 + 引用 + 拷贝 + 作用域

在Python中,变量是没有类型的,在使用变量的时候,不需要提前声明,只需要给这个变量赋值即可.但是,当用变量的时候,必须要给这个变量赋值:如果只写一个变量,而没有赋值,那么Python认为这个变量没有定义(not defined). 一.变量和对象 1. 可变对象和不可变对象 在Python中,对象分为两种:可变对象和不可变对象,不可变对象包括int,float,long,str,tuple等,可变对象包括list,set,dict等.需要注意的是:这里说的不可变指的是值的不可变.对于不可变类

python类与类之间的关系

在面向对象中,类和类之间也可以产生相关的关系类中的关系: 依赖关系是最轻的,最重的是继承关系,关联关系是比较微妙的 依赖关系执行某个动作的时候,需要xxx来帮助完成这个操作,此时的关系是最轻的.随时可以更换另外一个东西来完成此操作 1 class Person: 2 def f1(self,tools): # 通过参数的传递把另外一个类的对象传递进来 3 tools.run() 4 print('皮一下很开心') 5 class Computer: 6 def run(self): 7 prin

python 类与类之间的关系

一.依赖关系(紧密程度最低) (1)简单的定义:就是方法中传递一个对象.此时类与类之间存在依赖关系,此关系比较低. (2)实例植物大战僵尸简易版 题目要求:创建一个植物,创建一个僵尸 1.植物:名字.血量,攻击力 2.僵尸:名字.血量.攻击力 3.植物可以打僵尸,僵尸掉血 4.植物被僵尸咬,植物掉血 # 植物大战僵尸简易版 class ZhiWu:#创建植物类 def __init__(self,name,hp,attack):#初始化属性 self.name=name self.hp=hp s

Python包管理工具之间的关系

转自http://www.nowamagic.net/academy/part/13/302/ 当前的包管理工具链是 easy_install/pip + distribute/setuptools + distutils, 显得较为混乱. 而将来的工具链组合非常简单:pip + distutils2. 1. distutils : Python 自带的基本安装工具,适用于非常简单的应用场景,使用: 为项目创建 setup.py 脚本. 执行 setup.py install 可进行安装. 2.

浅谈javaScript数据类型、变量、内存之间的关系,文末有图解

一.变量是没有类型的 在JavaScript中,定义变量的方法是“var 变量名=变量值”,无论这个变量要给他赋值为一个数字.字符串还是数组,他的类型都不需要声明.也就是说如果我只声明了一个变量“var a”,而没有给他赋值,那么我可以给他赋任何值,在语法上都是没有问题的. 二.变量值是有类型的 尽管变量是没有类型的,使用typeof方法仍然能够获取到一个类型: var a; console.log(typeof(a));//值为undefined var a=1; console.log(ty

【转】python共享引用(多个变量引用)示例代码

python共享引用(多个变量引用)示例代码_python_脚本之家http://www.jb51.net/article/44109.htm python单个(一个)对象被多个变量引用又是怎么一回事儿呢?看下面代码 a = 3b = a 先上图(图1)吧,大家一看就一目了然了: 变量名和对象,在运行赋值语句b = a之后,变量a,b都指向了对象3的内存空间. 假设这时执行 a = 'python', a将指向刚创建的字符串对象. 我们再来试试这种情况: >>>list_1 = [1,2

Python 变量 对象 引用

1.变量 变量第一次赋值时被创建,变量在使用前必须赋值 变量本身没有类型,变量类型为它引用的对象类型: 变量在使用时被替换成它引用的对象 2.对象 对象本身具有计数和类型,变量引用对象,当对象的引用变为0的时候,回收对象内存.但是类似INT等小类型对象,不一定立马回收它的内存. 修改指向同一个可变对象的任何一个变量,都会影响到指向的对象,也就是两个变量的值都会被修改. >>> l=[1,2,9] >>> s= l >>> s[0]=11 >>

关于CGI:Tomcat、PHP、Perl、Python和FastCGI之间的关系

如前文所述,Web服务器是一个很简单的东西,并不负责动态网页的构建,只能转发静态网页.同时Apache也说,他能支持perl,生成动态网页.这个支持perl,其实是apache越位了,做了一件额外的事情. 现在我们看生成动态网页这件事情. CGI的定义是:外部应用程序与Web服务器之间的接口. 明白了吧?也就是说,所谓的动态网页,都是要外部应用程序生成的,而不是Web服务器能干的事情.所以,最初的.最简单的CGI,是使用C来写的,很简单. 到了后来,大家觉得老用C也不是个办法啊,效率这么慢,老板