python内存地址
小整数池(节省内存,提高执行效率)
Python实现int的时候有个小整数池。为了避免因创建相同的值而重复申请内存空间所带来的效率问题, Python解释器会在启动时创建出小整数池,范围是[-5,256],该范围内的小整数对象是全局解释器范围内被重复使用,永远不会被垃圾回收机制回收
在pycharm中运行python程序时,pycharm出于对性能的考虑,会扩大小整数池的范围,其他的字符串等不可变类型也都包含在内一便采用相同的方式处理了,我们只需要记住这是一种优化机制,至于范围到底多大,无需细究
1
'''[-5,256]范围内小整数'''
2
12 s =
3
12 f =
4
print(id(s),id(f))
5
4430852576 4430852576
6
12)) print(id(
7
4430852576
8
d = f
9
print(id(d))
10
4430852576
11
12
# 一旦发生数值计算(标识符d),可以发现标识符对应的内存地址立马改变,并且这个内存地址就是该常量的地址
13
1 d = d +
14
print(id(d))
15
4430852608
16
13)) print(id(
17
4430852608
18
19
'''超出范围[-5,256]后,内存地址将不同'''
20
9876 s =
21
9876 g =
22
print(id(s),id(g))
23
4449048976 4449105808
24
-6 d =
25
-6 f =
26
print(id(d),id(f))
27
4449105264 4449106096
28
-5 d =
29
-5 f =
30
print(id(d),id(f))
31
4430852032 4430852032
类似列表、元组等容器下的特殊情况(节省内存,提高执行效率)
同一个列表 或者元组 中,相同的值(无论是小整数、大整数、浮点数)会保存同一个地址
在不同的元组或者列表等容器类对象中,只要处于[-5,256]区间的数值,内存地址是一样的。以下说法和结论建立在~不在同一个代码块作用域内,相同代码块作用域又更特殊
1
# 同个列表下的元素,即便是大整数,内存地址也一样
2
1234567,1234567] gi = [
3
0]),id(gi[1])) print(id(gi[
4
4449104688 4449104688
5
6
# 不同列表下相同元素,符合小整数次策略的,内存地址一样,超出的将会为每个重新分配不同的地址
7
1,1,-6,-6] yu = [
8
0]),id(yu[1]),id(yu[2]),id(yu[3])) print(id(yu[
9
4430852224 4430852224 4449049072 4449049072
10
1,1,-6,-6] qw = [
11
0]),id(qw[1]),id(qw[2]),id(qw[3])) print(id(qw[
12
4430852224 4430852224 4449048912 4449048912
13
14
# 即便浮点数在同一个列表里,相同值也是同样的内存地址(主要是为了节省内存空间开辟,不过不同列表的话就不是了)
15
'''本来浮点数内存地址是不一样的,当处于同个列表下时,就一样了'''
16
24.3 s =
17
24.3 f =
18
print(id(s),id(f))
19
4431773272 4431773488
20
23.4,23.4,34] fff = [
21
0]),id(fff[1])) print(id(fff[
22
4431773632 4431773632
同个代码块内(节省内存,提高执行效率)
同个代码块内创建变量的值如果相同的话(尽管超出[-5,256]范围,又或者浮点数,又或者不同列表对象的相同值),那么他们的内存空间的值是相同的
1
# 同代码块作用域内,即便超出小整数池范围,内存地址也一样
2
def test():
3
7865 f =
4
7865 b =
5
print(id(f),id(b))
6
test()
7
4449106096 4449106096
8
9
# 同代码块作用域内,浮点值一样,内存地址一样
10
def test1():
11
78.987 f =
12
78.987 b =
13
print(id(f), id(b))
14
test1()
15
4449284288 4449284288
16
17
# 同代码块作用域内,即便不同的列表对象,只要值相同,内存地址就一样
18
def test2():
19
53453,-1,23] h = [
20
34,53453,56,67,-9] g = [
21
0]),id(g[1])) print(id(h[
22
test2()
23
4449105296 4449105296
总结
任何的内存地址复用,都是python解释器的一种优化策略(节省内存空间开辟,提高程序执行效率),我们懂了它这么做的理由就行