关于python中的对象是否可变是否不可变,第一步先了解一下python变量在内存中的存储逻辑(python中变量的地址有点像C语言中的指针):
python里面变量赋值之后会对值得引用有一个计数,当计数为0得时候就进行垃圾销毁。
至于引用计数怎么为0,如下例子就是:
a=5
b=6
a=6
a重新赋值之后指向的是6,此时对象A之前的引用5已经引用为0,就会被销毁
对象A和对象B现在的id值应该是一样的(id()返回对象的内存地址。)
a1=5
print(id(a1))
b1=6
print(id(b1))
print(a1)
print(b1)
a1=6
print(id(a1))
print(id(b1))
运行结果:
140737259607840
140737259607872
5
6
140737259607872
140737259607872
所以根据上述的一系列操作,变量的值和变量的地址是对应分配好了的,如果变量的值发生了变化,其实是将变量对应的地址都修改了,对应的值就是修改后对应的地址里面保存的值
所以不可变对象和可变对象的说法,其实是针对值变了之后对应的地址是否变化了,不可变对象就是相当于变化了值之后实际上相当于创建了一个新的对象,可变对象则是地址固定了,然后修改该值则该地址对应存储的值就会发生变化
def a(b=12):
print(b)
print(id(b))
b+=1
print(b)
print(id(b))
def b(num,c=[]):
print(id(c))
print(c)
for i in range(num):
c.append(i*2)
print(id(c))
print(c)
a()
print("+++++++++++++++++++")
a()
print("==================")
b(1)
print("**************************")
b(2)
运行结果:
12
140737259608064
13
140737259608096
+++++++++++++++++++
12
140737259608064
13
140737259608096
==================
2344326077312
[]
2344326077312
[0]
**************************
2344326077312
[0]
2344326077312
[0, 0, 2]
可以看出变量b的值对应的地址即id一直在发生变化(重新赋值即变化)
列表的值对应的地址没有变化,但是因为列表是可变对象,所以它的值会随着每一次的改变而改变
在Python中,数值类型int 、float、 字符串str 、元祖tuple、boole 都是不可变对象
列表list、集合set、字典dict都是可变对象