缓存介绍
为了增加程序的运行效率,Python3的解释器中实现了小数字和字符串缓存的机制,小数字的缓冲范围是[-5 ~ 256],字符串的缓存位数默认是20位。在Python程序中每次初始化一个新的变量就会在内存中开辟一块空间来存储这个变量,当变量不用的时候再回收这块内存。当大量出现这种操作的时候CPU就会发热,工作效率下降。为了减轻CPU的这种负担,Python3的解释器便实现了小数字和字符串的缓存机制。
演示说明
看下面代码,
a = 10 * 10
b = 100
print(id(a),id(b))
a = 10 * 10 * 10
b = 1000
print(id(a),id(b))
结果:
1711073600 1711073600
55698128 55697968
可以发现运行的结果中第一次a、b的地址一样,但是第二次的地址就不一样了。之所以会产生这样的结果就是因为第一次a计算出的结果属于[-5 ~ 256]这个缓存区间里,而第二次1000并不在这个区间中。所以会发生第二次a、b的地址不一样的现象。
字符串的默认缓存20位,可以看下面的代码:
str1 = "0123456789"
str2 = "0123456789"
print(id(str1),id(str2))
str3 = str1 + str2 + "0123456789"
str4 = "012345678901234567890123456789"
print(id(str3),id(str4))
结果:
44300392 44300392
44154456 44154568
默认参数不能使用可变类型数据
看下面的代码:
def func(list1 = []):
#print(id(list1))
list1.append(3)
print(list1)
func([1])
func([1])
func()
func()
func()
结果:
[1, 3]
[1, 3]
[3]
[3, 3]
[3, 3, 3]
不知道与你自己的答案是否一样呢?如果一样,恭喜你,对于可变数据类型已经领悟的很好了,不然你可能就还得多理解一下可变数据类型到底是什么意思!下面解释一下这个问题。为了方便理解,我把代码改成这种形式。去掉输出值的部分,输出每个部分的地址。
def func(list1 = []):
print(id(list1))
list1.append(3)
#print(list1)
list2 = [1]
list3 = [1]
print(id(list2))
print(id(list3))
print("+" * 10)
func(list2)
func(list3)
print("-" * 10)
func()
func()
func()
结果:
54524024
54525584
++++++++++
54524024
54525584
----------
20615120
20615120
20615120
在函数定义list2、list3都是只有一个元素1,前两次函数的调用就是把list2、list3分别作为函数实参传递过去,在函数func中可以发现两次调用的结果:第一次调用func函数中输出的list1的地址与list2一样,第二次调用func函数中输出的list1的地址与list3一样。所以他们实际上在内存中占用的不同的内存,因此两次输出的结果都是[1,3] 。后三次调用没有传函数实参,因此使用默认的参数,在func函数中发现三次的地址都是一样的,因此函数每次调用list1的就会改变一次。
这个例子说明函数的默认参数绝对不能使用可变数据类型,不然的话......,总之这个知识点还是有必要强调一下的。