Python中的可变类型与不可变类型

(1)任何一个对象a均有一个唯一的id识别号,用内置函数id(a)来获得该号。在Cpython中,id(a)表示对象a在内存中的地址。
id(object) -> integer

Return the identity of an object.  This is guaranteed to be unique among
simultaneously existing objects.  (Hint: it's the object's memory address.)

可以用"is"语句判断两个对象的识别号是否一致,例如 a is b,而a == b是比较两者的值。

(2)Python中的变量可分为可变类型和不可变类型。
不可变类型包括:数字、字符串、元组、布尔
可变类型包括:列表、字典、集合
不可变类型表示不允许变量的值发生变化,如果改变了变量的值,相当于是新建了一个对象。可变类型表示该类型的变量可以原地修改。

判断变量的类型是可变类型还是不可变类型,可以通过修改该变量前后id值是否发生变化来判断,如id发生变化,则为不可变类型,反之为可变类型。(注:元组不支持该操作,因为元组默认不可变)。

a = 3
print(id(a))
a = 4
print(id(a))

结果:
505986616
505986632
说明数字是不可变的,看似能修改变量a的值,其实a=4时, a的内存地址已变化。

b = 'hello'
print(id(b))
b = 'hello world'
print(id(b))

结果:
226397440
323543992
同样,字符串变量b看似能修改值,其实是在内存中新的地址创建了新的对象。

c = [1,2,3]
print(id(c))
c.append(4)
print(id(c))

d = {'a':1,'b':2,'c':3}
print(id(d))
d.pop('c')
print(id(d))

e={1,2,3}
print(id(e))
e.add(4)
e.remove(1)
print(id(e))

以上三段代码运行发现,修改列表、字典、集合变量的值时,变量的id值不发生任何改变,说明这三种数据类型均为可变类型。

(3)可变类型内部包含不可变类型的情况

a=['abc',1,2]
print(id(a),id(a[0]))
a[0] = 'efg'
print(id(a),id(a[0]))

运行结果:
322594056 12223552
322594056 325218816

说明修改可变类型变量列表内部的不可变对象字符串时,列表的id不发生变化,但内部的不可变类型对象的字符串对象的id值发生了变化。

(4)小数据池

a = 3
b = 3
print(id(a) == id(b))

运行结果:True

a = 300
b = 300
print(id(a) == id(b))

运行结果:False
Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。

对于字符串变量,当字符串的长度>1,且只含有大小写字母,数字,下划线时,才会默认驻留。当字符串变量的长度为0或者1,使用小数据池。

a = 'hello_2020'
b = 'hello_2020'
print(id(a) == id(b))

a = 'hello world'
b = 'hello world'
print(id(a) == id(b))

运行结果:
True
False

对于bool变量同样适用小数据池。

a = True
b = True
print(id(a) == id(b))

运行结果:
True

以上情况外,均不使用小数据池,例如:

a = [1,2,3,4]
b = [1,2,3,4]
print(id(a) == id(b))

运行结果:
False

(5)知识检验

例1:

a = 'abc'
a.capitalize()
print(a)

运行结果是 abc,为什么不是Abc?

例2:

a =[100,200,300]
a = a.append(400)
print(a)

运行结果:None,为什么不是[100, 200, 300, 400]

你可能感兴趣的:(Python基础)