python的缓存机制

python的缓存机制


前言

因为在创建数据时需要为数据创建内存,在销毁数据时需要释放内存,为了提高效率,Python使用了缓存机制。
什么是缓存机制呢?就是Python将一些值预先存好,当定义一个变量,并给他赋值时,会先匹配这些缓存好的值,如果有匹配的话,就将变量指向对应的内存。
那Python是不是将所有的值都预先存好了呢?显然是不可能的。在Python解释器启动时从内存空间中开辟出一小部分将一些比较常用的值预先定义好。
那今天我们就来了解一下,都有哪些预先存好的值。

id()函数

在进入正题之前,我们先了解一下id()函数:

id() 函数返回对象的唯一标识符,标识符是一个整数。
对应的内存地址是hex(id)

print(id(11), id("string"))

在这里插入图片描述

实例测试

先试试一个较小的值:

a = 11
b = 11

print(a is b)
print(id(a), id(b))

在这里插入图片描述
a和b的id值都是相同的,很显然他们指向了同一个内存地址。


再试试一个较大的值

c = 500
d = 500

print(c is d)
print(id(c), id(d))

在这里插入图片描述
当值为500时,id值已然不同。


我们用一个循环来看看具体有哪些值:

for num1, num2 in zip(range(-10, 500), range(-10, 500)):
    if id(num1) == id(num2):
        print(num1, end="\t")

在这里插入图片描述
由上可知预定义的值为 [-5, 256]


但是我还是有疑问,会不会是range()函数在搞鬼呢?

for num3 in range(-10, 500):
    if num3 == 11:
        print(id(num3) == id(11))

在这里插入图片描述


上面的例子都是int型的数据,那么boolstr类型的数据呢?
先试试bool

bool1 = True
bool2 = True

print(id(bool1), id(bool2))

在这里插入图片描述
bool值的id也是一样的


接下来是str

str1 = "aaa"
str2 = "aaa"
print(id(str1), id(str2))

在这里插入图片描述
这里的id也是相同的,但是这个值是我随意写的,不可能说Python解释器启动的时候就将这些值定好了吧?唯一合理的解释就是,我定义了str1之后,再定义str2时,会去检索是否已经定义过,如果已经定义,那么就将str2指向其地址。


那么怎么确定 **[-5, 256]**是一开始就创建好的呢?
我们反复运行开头的哪行代码,发现不管运行几次,都是相同的结果,

print(id(11), id("string"))

在这里插入图片描述
但是,如果重启运行时,
在这里插入图片描述
在这里插入图片描述

再运行,就会发现id(11)的值跟之前的是一样的,而id("string")的值跟之前不一样了,再继续运行时,则不会再变了。


如果是List(列表)、Tuple(元组)、Dictionary(字典)等数据类型的值呢?

list1 = [2, 2, 257]
list2 = [2, 257, 257]
print("2: ", id(list1[0]), id(list1[1]), id(list2[0]))
print("257:", id(list2[1]), id(list2[2]), id(list1[2]))
print("\n")

tuple1 = (2, 2, 257)
tuple2 = (2, 257, 257)
print("2: ", id(tuple1[0]), id(tuple1[1]), id(tuple2[0]))
print("257:", id(tuple2[1]), id(tuple2[2]), id(tuple1[2]))

在这里插入图片描述
对于257,list1和list2的257id的值是不同的,而同在list2中的257的id的值却是相同的;tuple中也是同样的;
对于整数2,不管是list1,list2,还是tuple1, tuple2的id的值都是相同的。

dict1 = {"a1": 2, 
         "a2": 2, 
         "a3": 257,
         2: "abc"
        }
dict2 = {"a1": 257, 
         "a2": 257, 
         "a3": 2,
         257: "abc"
        }
print("2:", id(dict1["a1"]), id(dict1["a2"]), id(dict2["a3"]))
print("\nstr key:")
for i in dict1.keys():
    print(id(i))
print("\n")
print("257:", id(dict2["a1"]), id(dict2["a2"]), id(dict1["a3"]))
print("\nstr key:")
for i in dict2.keys():
    print(id(i))
print("\nabc: ", id(dict1[2]), id(dict2[257]))

在这里插入图片描述
对于整数2,在dict1和dict2中不管是作为键还是值,id都是相同的;
对于整数257, id(dict2[“a1”])和id(dict2[“a2”])的值相同,但与id(dict1[“a3”])不同;
对于字符串,在dict1和dict2中不管是作为键还是值,id都是相同的。


那要是在不同的作用域呢?

int1, int2 = 2, 257
str1 = "abcd"

def func():
    int3, int4 = 2, 257
    print("id(int1) == id(int3):", \
          id(int1) == id(int3),\
          "\nid(int2) == id(int4):",\
          id(int2) == id(int4))
    str2 = "abcd"
    print("id(str1) == id(str2):", id(str1) == id(str2))
    
func()

在这里插入图片描述
由此可见,预先定义的值是全局的,字符串也是全局的


下面这个图从参考链接而来,但是小数部分却得出了不同的结果:
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ayiya_Oese

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值