Python中的可变,不可变对象;值类型,引用类型;浅拷贝,深拷贝理解
2017-12-31 15:09
507 查看
乍一看,好像有一些相通之处。
python中不可变类型有int,sring,tuple
可变类型有list和dict
看下面代码:
可以看到,int类型只要改变就是整个值得改变,而list类型的改变是内部元素的改变,当list整个全部改变的时候,它在内存中的地址也会发生变换,那么string呢,在C语言中string不也是一串char吗,看看
也就是是说在python中string不能像list一样理解,它是不可只改变内部元素值的,只要变就是全部变
总结: 可变对象和不可变对象的区别在于这个对象指向的这个地址是否允许它改变,允许则可变,不允许则不可变,如果要变,就要挪地方(改变地址)
看代码
想必已经很清晰了,可变对象和不可变对象,值类型和引用类型本质上是一样一样的东西,由于对象的可变与不可变才导致了对象是引用类型或者值类型
所以,值类型有int, string ,tuple等,
引用类型有list,dict等
其中lb,lc是浅拷贝,ld是深拷贝,浅拷贝是把对象内部的对象都看成可变类型来处理,而深拷贝是把对象内部的对象是否可变都分的很清楚。
注意: 浅拷贝时
1. 可变对象和不可变对象
python中一切对象,类型也是对象python中不可变类型有int,sring,tuple
可变类型有list和dict
看下面代码:
# 不可变对象 >>> a = 1 >>> id(a) 1752564208 >>> a = 2 >>> id(a) 1752564240 #可变对象 >>> la = [1,2,3] >>> id(la) 2006131817800 >>> la[0] = 5 >>> id(la) 2006131817800 >>> la = [3,4,5] >>> id(la) 2006131818248
可以看到,int类型只要改变就是整个值得改变,而list类型的改变是内部元素的改变,当list整个全部改变的时候,它在内存中的地址也会发生变换,那么string呢,在C语言中string不也是一串char吗,看看
>>> str = "hello" >>> id(str) 2006131950176 >>> str[0] 'h' >>> str[0] = "w" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment
也就是是说在python中string不能像list一样理解,它是不可只改变内部元素值的,只要变就是全部变
总结: 可变对象和不可变对象的区别在于这个对象指向的这个地址是否允许它改变,允许则可变,不允许则不可变,如果要变,就要挪地方(改变地址)
2. 值类型和引用类型
前面已经说了可变类型与不可变类型了,值类型和引用类型与前面的概念十分相似。看代码
# 值类型 >>> a = 1 >>> b =a >>> id(a) 1752564208 >>> id(b) 1752564208 >>> b = 2 >>> id(b) 1752564240 >>> id(a) 1752564208 #引用类型 >>> la = [1,2,3] >>> lb = la # lb是la的引用 >>> id(la) 1978265648264 >>> id(lb) 1978265648264 >>> lb[0] = 5 # 改变引用对象中单个元素 >>> lb [5, 2, 3] >>> la [5, 2, 3] >>> id(lb) 1978265648264 >>> id(la) 1978265648264 >>> lb = [2,3,4] # 改变引用对象中所有元素的值 >>> la [5, 2, 3] >>> lb [2, 3, 4] >>> id(la) 1978265648264 >>> id(lb) 1978265648904
想必已经很清晰了,可变对象和不可变对象,值类型和引用类型本质上是一样一样的东西,由于对象的可变与不可变才导致了对象是引用类型或者值类型
所以,值类型有int, string ,tuple等,
引用类型有list,dict等
3. 浅拷贝,深拷贝
知道了可变与不可变的intuition之后,浅拷贝和深拷贝就很简单了,区别在于,前面两种看的是他们的区别,而拷贝着重的他们的相同,看代码:>>> la = [1,2,[3,4,5]] >>> lb = la >>> [id(x) for x in la] [1752564208, 1752564240, 2065380752328] >>> [id(x) for x in lb] [1752564208, 1752564240, 2065380752328] >>> lc = copy.copy(la) >>> [id(x) for x in lc] [1752564208, 1752564240, 2065380752328] >>> ld = copy.deepcopy(la) >>> [id(x) for x in ld] [1752564208, 1752564240, 2065380752200] >>> id(la) 2065380751880 >>> id(lb) 2065380751880 >>> id(lc) 2065380638792 >>> lc[2 4000 ][0] = 0 >>> lc [1, 2, [0, 4, 5]] >>> la [1, 2, [0, 4, 5]] >>> ld[2][0] = 9 >>> ld [1, 2, [9, 4, 5]] >>> la [1, 2, [0, 4, 5]]
其中lb,lc是浅拷贝,ld是深拷贝,浅拷贝是把对象内部的对象都看成可变类型来处理,而深拷贝是把对象内部的对象是否可变都分的很清楚。
注意: 浅拷贝时
lc[2][0] = 0虽然只是改变了第三个元素的第一个值但是不能写
lc[2] = [0,4,5],因为这样写的话,解释器会认为你是全部改变了这个可变类型的值,从而重新给lc一个地址
相关文章推荐
- 理解python可变类型vs不可变类型,深拷贝vs浅拷贝
- python可变类型vs不可变类型,深拷贝vs浅拷贝
- python中数据类型(对象)的可变和不可变性
- python 传值 传引用 可变对象 不可变对象 的区别与联系
- python函数参数是值传递还是引用传递:取决于对象内容可变不可变
- Python 引用 :可变类型和不可变类型
- python引用在函数传参时的体现以及可变与不可变对象的对比
- Python学习笔记——可变类型&不可变类型&深拷贝&浅拷贝
- Python可变对象v.s.不可变对象,引用
- python作用域的补充,局部引用全局作用域的修改尝试,可变类型内部可修改,内存指向不可变
- JavaScript权威指南_10_第3章_类型/值/变量_3.7-不可变的原始值和可变的对象引用
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
- Python基础:Python可变对象和不可变对象
- Python中的可变对象和不可变对象
- Python 初体验之 对象的引用和拷贝
- Python(可变/不可变类型,list,tuple,dict,set)
- python 可变不可变类型
- python 对象拷贝——浅拷贝和深拷贝 之函数传递——值传递还是引用传递?
- python数字类型介绍以及创建数字值对象引用、删除数字值引用操作实例