016—数据缓存机制-小数据池

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
上一篇:编写脚本 systeminfo.sh,显示当前主机系统信息,包括:主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小


下一篇:android studio can‘t resolve the symbol R.id.xxxxxxxx,R.layout.xxxxxxxx,报红,但是能编译通过的解决方法