测试环境:Mac OS + Python3.7.4。
在同一文件里
在同一文件中针对各基本类型的变量做如下测试:
# 在同一文件中
# 测试环境:MacOS Python3.7.4
# 1、对于整型而言,有相同值的两个变量在内存中的 id 值一致。
a = -12342143124
b = -12342143124
print(id(a) == id(b)) # True
a = 234324324234
b = 234324324234
print(id(a) == id(b)) # True
# 2、对于浮点数而言,有相同值的两个变量在内存中的 id 值一致。
a = -12313131313.213133213
b = -12313131313.213133213
print(id(a) == id(b)) # True
a = 342442342342.4324234
b = 342442342342.4324234
print(id(a) == id(b)) # True
# 3、对于布尔值而言,有相同值的两个变量在内存中的 id 值一致。
a = True
b = True
print(id(a) == id(b)) # True
a = False
b = False
print(id(a) == id(b)) # True
# 4、对于虚数而言,有相同值的两个变量在内存中的 id 值一致。
a = 1213213213123j
b = 1213213213123j
print(id(a) == id(b)) # True
a = -123213213213123j
b = -123213213213123j
print(id(a) == id(b)) # True
# 5、对于复数而言,有相同值的两个变量在内存中的 id 值一致。
a = 213213231312 + 324324234j
b = 213213231312 + 324324234j
print(id(a) == id(b)) # True
a = -21321321321 - 3244324234j
b = -21321321321 - 3244324234j
print(id(a) == id(b)) # True
# 6、对于字符串而言,有相同值的两个变量在内存中的 id 值一致。
a = 'abcd$234234@342^^&'
b = 'abcd$234234@342^^&'
print(id(a) == id(b)) # True
# 7、对于元组而言,有相同值的两个变量在内存中的 id 值一致。
a = tuple()
b = tuple()
print(id(a) == id(b)) # True
a = (12312312421, 123123, 4324, 'deawda', '@#$@$%@')
b = (12312312421, 123123, 4324, 'deawda', '@#$@$%@')
print(id(a) == id(b)) # True
# 8、对于列表而言,有相同值的两个变量在内存中的 id 值不一致。
a = []
b = []
print(id(a) == id(b)) # False
a = [1, 2, 3]
b = [1, 2, 3]
print(id(a) == id(b)) # False
# 9、对于集合而言,有相同值的两个变量在内存中的 id 值不一致。
a = set()
b = set()
print(id(a) == id(b)) # False
a = {1, 2, 3}
b = {1, 2, 3}
print(id(a) == id(b)) # False
# 10、对于字典而言,有相同值的两个变量在内存中的 id 值不一致。
a = {}
b = {}
print(id(a) == id(b)) # False
a = {'zs':12,'ls':20}
b = {'zs':12,'ls':20}
print(id(a) == id(b)) # False
小结一下,在同一文件中并且值相同的两个变量:
- 如果它们是 Number 类型(int、float、bool、complex) 、字符串类型或元组类型时,它们的值在内存中的地址肯定相同;
- 如果它们是列表、集合或字典类型,它们的值在内存中的地址肯定不同;
在不同文件里
数字类型测试
>>> a = -6
>>> b = -6
>>> id(a) == id(b)
False
>>> a = -5
>>> b = -5
>>> id(a) == id(b)
True
>>> a = 256
>>> b = 256
>>> id(a) == id(b)
True
>>> a = 257
>>> b = 257
>>> id(a) == id(b)
False
>>> a = 1.2
>>> b = 1.2
>>> id(a) == id(b)
False
>>> a = True
>>> b = True
>>> id(a) == id(b)
True
>>> a = 1 + 2j
>>> b = 1 + 2j
>>> id(a) == id(b)
False
小结:
- 两个文件中变量值类型为整型、值相同、且范围在 -5 ~ 256 时;
- 两个文件中变量值类型为布尔、且值相同时;
它们就指向内存中的同一块地址。
字符串测试
>>> a = '#'
>>> b = '#'
>>> id(a) == id(b)
True
>>> a = 'a'
>>> b = 'a'
>>> id(a) == id(b)
True
>>> a='abcdawedea_123'
>>> b='abcdawedea_123'
>>> id(a) == id(b)
True
>>> a='abc#'
>>> b='abc#'
>>> id(a) == id(b)
False
小结:
- 两个文件中变量值类型为字符串、值相同、且字符串长度等于 1;
- 两个文件中变量值类型为字符串、值相同、字符串长度大于 1、且只含有大小写字母、数字、下划线时;
它们就指向内存中的同一块地址。
使用乘号得到的字符串
>>> a = 'abc#'
>>> b = a * 1
>>> c = a * 1
>>> id(b) == id(c)
True
>>> b = a * 2
>>> c = a * 2
>>> id(b) == id(c)
False
>>> a = 'abc'
>>> b = a * 2
>>> c = a * 2
>>> id(b) == id(c)
False
小结:用 *
号得到的字符串,当乘数等于 1 时,无论什么字符串 * 1,都默认指向内存中的同一块地址。
小结
对于整数而言:
- Python 在内存中创建了 -5 ~ 256 范围的整数,提前驻留在了内存的一块区域,这个区域也叫做小数据池。如果是不同文件(模块)的两个变量声明了在 -5 ~ 256 之间的同一个值,那么这两个变量的 id 就一致,即这两个变量的值都同时指向一个值的地址,以达到节省空间的目的。
对于普通字符串而言:
- 字符串的长度为 0 或者 1 时,默认驻留小数据池;
- 字符串的长度大于 1,且只含有大小写字母,数字,下划线时,默认驻留小数据池;
对于用 *
复制的字符串而言:
- 用
*
号复制得到的字符串,只有当乘数等于 1 时,无论什么字符串 * 1,都会让这个字符串被缓存,后续有通过 * 1 复制相同字符串时,就默认使用这个缓存的字符串;
无论是变量缓存机制还是小数据池的驻留机制,都是为了节省内存空间,提升代码的执行效率。
指定驻留到小数据池
我们可以通过 sys
模块中的 intern
函数让指定的数据驻留到小数据池,例:
>>> from sys import intern
>>> a = 'abc#'
>>> b = 'abc#'
>>> id(b) == id(c)
>>> a = intern('abc#')
>>> b = intern('abc#')
>>> id(a) == id(b)
True
评论区