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