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

mac2024-03-06  37

(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]

最新回复(0)