Python 赋值操作中的可变对象和不可变对象
2022-04-11 本文已影响0人
升不上三段的大鱼
Python 中如果想要进行赋值操作,很简单, b=a
,完事了,但是在后续操作里可能会有一些很难发现的bug。
例子1:如果a
是整数
>>> a = 2
>>> id(a)
2659777866064
>>> b = a
>>> id(b)
2659777866064
>>> b += 1
>>> id(b)
2659777866096
>>> print(a, b)
2 3
看起来完全合理,赋值操作之后 b=2,执行加法操作之后 b=3。
例子2:a
是 list
>>> a = [1,2,3]
>>> b = a
>>> id(a)
2659828800704
>>> id(b)
2659828800704
>>> b.append(4)
>>> id(b)
2659828800704
>>> b
[1, 2, 3, 4]
>>> a
[1, 2, 3, 4]
大事不妙, 在对b进行操作之后 a怎么也跟着变了。
在例子1中,a是数字,是不可变对象,b=a赋值之后,b的id和a一样,可以理解为ab都指向同一块内存2,但b+=1操作让b指向了3的内存,b的id发生了改变。
例子2中, a 是可变对象, b=a赋值之后,b的id和a一样,同样意味着ab都指向同一块内存,但是这块内存里的对象是可以变的,因此b.append(4)在b指向的list里加入了4,a与b指向同一内存,所以a的值也变了。
Python 中不可变对象有数字、字符串、元组,可变对象有字典、列表、字节数组。
在使用可变对象进行赋值、传参等操作的时候,要特别小心发生这种修改了原始对象的bug,最稳妥的方法是再拷贝一个,需要注意的是 list的切片操作相当于浅拷贝,list2 = list1[:]
,对list2的操作并不会影响到list1.