python解释器启动时,会将使用频率高的数据提前存入内存中,当需要使用这些数据时,就不变开辟内存存储了,直接引用即可
同一个代码块内
在同一个代码块内,python在初始化对象时,会检查是否已经创建了,如果创建了,那么就重用
数据类型 | 缓存机制 |
---|---|
int | 所有数字 |
float | 所有浮点数 |
bool | 所有布尔值 |
str | 所有字符串(3.6版本符合规则的字符串才会缓存) |
# int类型
i = 20191230
print(id(i)) # 140372986331696
n = 20191230
print(id(n)) # 140372986331696
# float类型
i = 68.43234554353
print(id(i)) # 140702723708048
n = 68.43234554353
print(id(n)) # 140702723708048
# bool值
i = True
print(id(i)) # 4538243512
n = True
print(id(n)) # 4538243512
python3.6中字符串
# 静态初始化的字符串,都满足缓存机制
a = '骨头abcdefghij01234567'
b = '骨头abcdefghij01234567'
print(a, id(a), len(a)) # 骨头abcdefghij01234567 140197373545776 20
print(b, id(b), len(b)) # 骨头abcdefghij01234567 140197373545776 20
a = '骨头abcdefghij01234567x'
b = '骨头abcdefghij01234567x'
print(a, id(a), len(a)) # 骨头abcdefghij01234567x 140332248130352 21
print(b, id(b), len(b)) # 骨头abcdefghij01234567x 140332248130352 21
# 拼接的字符串中包含除了字母、数字、下划线以外的字符,不满足缓存机制
a = 'abcdefg' + '骨头hij01234'
b = 'abcdefg骨头hij0123' + '4'
print(a, id(a), len(a)) # abcdefg骨头hij01234 140332248211840 17
print(b, id(b), len(b)) # abcdefg骨头hij01234 140332248211952 17
# # 拼接的字符串中不包含除了字母、数字、下划线以外的字符,满足缓存机制
a = 'abcdefg' + '_hij01234'+'_hij01234'
b = 'abcdefg_hij0123' + '4'+'_hij01234'
print(a, id(a), len(a)) # abcdefg_hij01234_hij01234 140496059701808 25
print(b, id(b), len(b)) # abcdefg_hij01234_hij01234 140496059701808 25
# 乘法得到的字符串,字符串不包含除数字、字母、下划线以外的字符,并且长度小于等于20时,满足缓存机制
a = 'abcdefg_21' * 2
b = 'abcdefg_21' * 2
print(a, id(a), len(a)) # abcdefg_21abcdefg_21 140304140102584 20
print(b, id(b), len(b)) # abcdefg_21abcdefg_21 140304140102584 20
# 乘法得到的字符串,字符串不包含除数字、字母、下划线以外的字符,并且长度大于20时,不满足缓存机制
a = 'abcdefg_2q1' * 2
b = 'abcdefg_2q1' * 2
print(a, id(a), len(a)) # abcdefg_2q1abcdefg_2q1 140324504607456 22
print(b, id(b), len(b)) # abcdefg_2q1abcdefg_2q1 140324504607600 22
# 乘法得到的字符串,字符串包含除数字、字母、下划线以外的字符,长度小于于20时,不满足缓存机制
a = 'abcdefg2@' * 2
b = 'abcdefg2@' * 2
print(a, id(a), len(a)) # abcdefg21@ 140334246800944 10
print(b, id(b), len(b)) # abcdefg21@ 140334246800944 10
python3.8中字符串
第一次用3.8版本,突然发现字符串对象只要值一样的,那么就是同一个对象
应该是python的优化(有知道的大佬求指教),如下例子
a = '骨头abcdefghij01234567'
b = '骨头abcdefghij01234567'
print(a, id(a), len(a)) # 骨头abcdefghij01234567 140322610081072 20
print(b, id(b), len(b)) # 骨头abcdefghij01234567 140322610081072 20
a = '骨头abcdefghij01234567x'
b = '骨头abcdefghij01234567x'
print(a, id(a), len(a)) # 骨头abcdefghij01234567x 140322625590832 21
print(b, id(b), len(b)) # 骨头abcdefghij01234567x 140322625590832 21
a = 'abcdefg' + '骨头hij01234'
b = 'abcdefg骨头hij0123' + '4'
print(a, id(a), len(a)) # abcdefg骨头hij01234 140322626141632 17
print(b, id(b), len(b)) # abcdefg骨头hij01234 140322626141632 17
a = 'abcdefg' + '_hij01234'+'_hij01234'
b = 'abcdefg_hij0123' + '4'+'_hij01234'
print(a, id(a), len(a)) # abcdefg_hij01234_hij01234 140322625578848 25
print(b, id(b), len(b)) # abcdefg_hij01234_hij01234 140322625578848 25
a = 'abcdefg_21' * 2
b = 'abcdefg_21' * 2
print(a, id(a), len(a)) # abcdefg_21abcdefg_21 140322625693936 20
print(b, id(b), len(b)) # abcdefg_21abcdefg_21 140322625693936 20
a = 'abcdefg_2q1' * 2
b = 'abcdefg_2q1' * 2
print(a, id(a), len(a)) # abcdefg_2q1abcdefg_2q1 140322625693616 22
print(b, id(b), len(b)) # abcdefg_2q1abcdefg_2q1 140322625693616 22
a = 'abcdefg2@' * 2
b = 'abcdefg2@' * 2
print(a, id(a), len(a)) # abcdefg2@abcdefg2@ 140322626273488 18
print(b, id(b), len(b)) # abcdefg2@abcdefg2@ 140322626273488 18
不同代码块
python会把-5~256的整数进行缓存,当将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象
数据类型 | 缓存机制 |
---|---|
int | -5~256 |
bool | 所有布尔值 |
str | 符合规则的字符串才会缓存 |
# int类型
>>> s = -3
>>> n = -3
>>> a = 256
>>> b = 256
>>> c = 257
>>> d = 257
>>> id(s)
4397246688
>>> id(n)
4397246688
>>> id(a)
4397254976
>>> id(b)
4397254976
>>> id(c)
140408179041584
>>> id(d)
140408179041232
# bool类型
>>> s = True
>>> a = True
>>> id(s)
4397025720
>>> id(a)
4397025720
# 静态初始化的字符串,满足缓存
>>> s = 'hello_world1234512341hello_world1234512341'
>>> n = 'hello_world1234512341hello_world1234512341'
>>> id(s)
140346499569680
>>> id(n)
140346499569680
>>> s = ''
>>> n = ''
>>> id(s)
140408157164272
>>> id(n)
140408157164272
>>>
>>> s = 'a'
>>> n = 'a'
>>> id(s)
140408179062448
>>> id(n)
140408179062448
>>>
>>> s = '$'
>>> n = '$'
>>> id(s)
140408179064048
>>> id(n)
140408179064048
# 拼接的字符串中包含除了字母、数字、下划线以外的字符,不满足缓存机制
>>> s = 'abcdefg' + '骨头hij01234'
>>> n = 'abcdefg' + '骨头hij01234'
>>> id(s)
140346497641248
>>> id(n)
140346498128448
# 拼接的字符串只是由数字、字母、下划线组成的字符串,满足缓存
>>> s = 'helloworld' + '__12341234'
>>> len(s)
20
>>> n = 'helloworld__' + '12341234'
>>> id(s)
140346499694000
>>> id(n)
140346499694000
>>> s = 'helloworld' + '__123412345' + 'qwerty'
>>> n = 'helloworld_' + '_1234123' + '45qwerty'
>>> id(s)
140346499695360
>>> id(n)
140346499695360
# 乘法得到的字符串,字符串不包含除数字、字母、下划线以外的字符,并且长度小于等于20时,满足缓存机制
>>> a = 'abcdefg_21' * 2
>>> b = 'abcdefg_21' * 2
>>> id(a)
140346499694000
>>> id(b)
140346499694000
# 乘法得到的字符串,字符串不包含除数字、字母、下划线以外的字符,并且长度大于20时,不满足缓存机制
>>> a = 'abcdefg_21a' * 2
>>> b = 'abcdefg_21a' * 2
>>> id(a)
140346499694216
>>> id(b)
140405330050768
# 乘法得到的字符串,字符串包含除数字、字母、下划线以外的字符,长度小于于20时,不满足缓存机制
>>> a = 'asd@'*2
>>> b = 'asd@'*2
>>> id(a)
140405330036080
>>> id(b)
140405330036400
指定缓存字符串
使用 sys 模块 的 intern 方法,可以将字符串加入数据池将其缓存,只在内存中创建一个对象
from sys import intern
a = 'asd@'*30
b = 'asd@'*30
print(id(a),id(b)) # 140686759084960 140686759085136
x = intern('asd@'*30)
y = intern('asd@'*30)
print(id(x),id(y)) # 140686759085312 140686759085312