Python魔法缓存,以数字开始
众所周知,Python是弱类型的脚本语言,变量的定义是不用声明类型的。
a = 1
Python所有数字的本质都是对象, 他们是不可改变的数据类型,这意味着改变数字数据类型会分配一个新的对象。 而变量名实际上创建了一个引用指向该数字。
我们可以用del语句删除该引用。
a = 1
print(a)
>>> 1
del a
print(a)
>>>Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
那么就有个问题,Python解释器如果每次都判断类型再创建引用,岂不是很慢?
所以Python缓存了[-5,256]范围内常用的整数 ,他们不会被垃圾回收机制回收。于是我们在Python Shell里输入如下代码,会产生神奇的现象。
>>> a = 1
>>> b = 1
>>> a == b
>>> True
>>> a is b
>>> True
>>> a = 1000
>>> b = 1000
>>> a == b
>>> True
>>> a is b
>>> False
所以期望该范围内的整数也是相同的,可以理解为两个变量创建了同一个引用。"=="比较的是二者的引用对象的内容。"is"比较的是两个引用对象的id,也就是比较两个对象是否为同一个实例化对象,是否指向同一个内存地址。
但是,如果把代码放入同一个文件。结果会大不相同。
a = 300
b = 300
print(a is b)
>>> True
简单理解,Python解释器会分析整个文件,做出如下举动:
Python在执行同一个代码块的初始化对象的命令时,会检查是否其值是否已经存在,如果存在,会将其重用。
那么哪些变量会有以上机制呢?
- int(float): 任何数字在同一代码块下都会复用。
- bool: True和False
- String: 几乎所有的字符串都会符合缓存机制
例如,
a = "a"
b = "a"
print(a is b)
>>> True
但是字典并不会
a = {1: 2}
b = {1: 2}
print(a is b)
>>> False
而Shell中只会一行一行的处理数据,所以无法达到文件的效果。但是如果我们在Shell里这么写。说明Python解释器在读取第一行的时候,分析了两个变量的值,并知道二者相等,所以引用到同一对象。
>>> a = 1000;b = 1000
>>> a is b
>>> True
至于更底层的原因,作者还不太知道,在这儿先填个坑,学成之后再解释。
原文地址:https://www.cnblogs.com/scyq/p/12001862.html
时间: 2024-10-01 02:04:59