您的位置:首页 > 编程语言 > Python开发

Python中的可变,不可变对象;值类型,引用类型;浅拷贝,深拷贝理解

2017-12-31 15:09 579 查看
乍一看,好像有一些相通之处。

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
相关文章推荐