Python 在存储数据时,会根据数据的读取频繁程度以及内存占用情况来考虑,是否按照一定的规则将数据存储缓存中。那么问题来了,内存重用机制适用于哪些基本数据类型呢?
表 1 罗列了 Python 是否将指定数据存入缓存中的规则:
数据类型 | 是否可以重用 | 生效范围 |
---|---|---|
范围在 [-5, 256] 之间的小整数 | 如果之前在程序中创建过,就直接存入缓存,后续不再创建。 | 全局 |
bool 类型 | ||
字符串类型数据 | ||
大于 256 的整数 | 只要在本代码块内创建过,就直接缓存,后续不再创建。 | 本代码块 |
大于 0 的浮点型小数 | ||
小于 0 的浮点型小数 | 不进行缓存,每次都需要额外创建。 | |
小于 -5 的整数 |
下面直接通过一段程序来演示 Python 缓存机制的规则。
#范围在 [-5, 256] 之间的小整数 int1 = -5 int2 = -5 print("[-5, 256] 情况下的两个变量:", id(int1), id(int2)) #bool类型 bool1 = True bool2 = True print("bool类型情况下的两个变量:",id(bool1),id(bool2)) #对于字符串 s1 = "3344" s2 = "3344" print("字符串情况下的两个交量", id(s1), id(s2)) #大于 256 的整数 int3 = 257 int4 = 257 print("大于 256 的整数情况下的两个变量", id(int3), id(int4)) #大于 0 的浮点数 f1 = 256.4 f2 = 256.4 print("大于 0 的浮点数情况下的两个变量", id(f1), id(f2)) #小于 0 的浮点数 f3 = -2.45 f4 = -2.45 print("小于 0 的浮点数情况下的两个变量", id(f3), id(f4)) #小于 -5 的整数 n1 = -6 n2 = -6 print("小于 -5 的整数情况下的两个变量", id(n1), id(n2))
注意,此程序中,大量使用 id() 内置函数,该函数的功能是获取变量(对象)所在的内存地址。运行该程序,其输出结果为:
[-5, 256] 情况下的两个变量: 1792722416 1792722416
bool类型情况下的两个变量: 1792241888 1792241888
字符串情况下的两个交量 2912801330712 2912801330712
大于 256 的整数情况下的两个变量 2912801267920 2912801267920
大于 0 的浮点数情况下的两个变量 2912762210728 2912762210728
小于 0 的浮点数情况下的两个变量 2912762211016 2912762211040
小于 -5 的整数情况下的两个变量 2912801267952 2912801267984
以上输出结果中,每行都输出了 2 个相对应的变量所在的内存地址,如果相等,则表明 Python 内部对其使用了缓存机制,反之则没有。读者可对照以上输出结果来理解表 1 中有关变量缓存机制的规则。
另外,对于表 1 中所提到的代码块,Python 中的函数和类都被认为是在程序中开辟了一块新的代码块。以函数为例,函数内部的代码分属一个代码块,函数外部的代码属于另一个代码块。
有关函数的具有用法,后续章节会详细介绍,这里读者只需要知道函数中包含的代码,属于一个新的代码块即可。
由表 1 可以看到,Python 缓存机制在不同的代码块中也会有不同的表现。举一个例子,在上面例子代码的基础上,继续编写如下程序:
def fun(): #[-5,256] int1 = -5 print("fun中 -5 的存储状态",id(int1), id(int2)) #bool类型 bool3 = True print("fun中 bool 类型的存储状态",id(bool3),id(bool2)) #字符串类型 s1 = "3344" print("fun 中 3344 字符串的存储状态", id(s1), id(s2)) #大于 256 int3 = 257 print("fun中 257 的存储状态", id(int3), id(int4)) #浮点类型 f1 = 256.4 print("fun 中 256.4 的存储状态",id(f1), id(f2)) #小于 -5 n1 = -6 print("fun 中 -6 的存储状态", id(n1), id(n2)) fun()
输出结果为:
fun中 -5 的存储状态 1792722416 1792722416
fun中 bool 类型的存储状态 1792241888 1792241888
fun 中 3344 字符串的存储状态 1976405206496 1976405206496
fun中 257 的存储状态 1976405225648 1976405225680
fun 中 256.4 的存储状态 1976394459752 1976394459872
fun 中 -6 的存储状态 1976404744880 1976405225744
根据输出结果可以分析出:
- 从 -5 、bool 类型以及字符串 "3344" 的输出结果可以得知,无论是在同一代码块,还是不同的代码块,它们都使用相同的缓存内容;
- 从 257 和 256.4 的输出结果可以得知,如果位于同一代码块,则使用相同的缓存内容;反之,则不使用;
- 从 -6 的输出结果得知,Python 没有对其缓存进行操作。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/23149.html