探究 python 是不是用了一个整数缓冲池缓存了指定范围的整数
想法来自于 https://blog.csdn.net/qq_43657442/article/details/108384183
正文
上一篇末尾提到 ,我想个办法从 id 获得值。来测试一下,看看我在程序里面初始化 a = [1,2,3,4],然后我取最后一个元素(4)的 id 加 32 位 ,把这个 id 的值取出来看看是不是 5
先实现下看看效果
import ctypes
a = [1,2,3,4]
print("最后一个元素(4)的id是:", id(a[-1]))
address1 = id(a[-1])
get_value1 = ctypes.cast(address1, ctypes.py_object).value # 读取地址中的变量
print("测试我们通过地址取值的有效性:",get_value1)
address = address1 + 32
get_value = ctypes.cast(address, ctypes.py_object).value # 读取地址中的变量
print("整数4的地址往后移动32位存放的值是:",get_value)
输出
最后一个元素(4)的id是: 8791254619264
测试我们通过地址取值的有效性: 4
整数4的地址往后移动32位存放的值是: 5
注:id() 函数返回的地址是 int 型的,所以我直接加 32 是行的通的
证明了 python 的确是用了一个整数缓冲池缓存了指定范围的整数,不过这个范围有多大呢
测试边界范围
我手动测试了一遍发现范围是 -5 — 256
import ctypes
a = [1,2,3,4]
print("最后一个元素(4)的id是:", id(a[-1]))
address1 = id(a[-1])
get_value1 = ctypes.cast(address1, ctypes.py_object).value # 读取地址中的变量
print("测试我们通过地址取值的有效性:",get_value1)
address = address1 + 32*(-9) # 此时输出 -5
# address = address1 + 32*(252) #此时输出 256
get_value = ctypes.cast(address, ctypes.py_object).value # 读取地址中的变量
print("整数4的地址往后移动32位存放的值是:",get_value)
当 +32*(253)
时
Fatal Python error: GC object already tracked
Current thread 0x00000b88 (most recent call first): File
"d:/\u5404\u79cd\u6587\u4ef6\u5939/\u5b66\u4e60\u8d44\u6599/matplotlib.pyplot\u5e93\u7ed8\u56fe\u4ee3\u7801\u53ca\u89c6\u9891/plttest.py",
line 112 in
初此之外的 +32*(254)
、 +32*(255)
、 +32*(1000)
、 +32*(-10)
、 +32*(-11)
、 +32*(25)
等其他超出 -5 — 256
范围的都是没有输出,
可能是在调用 ctypes.cast(address, ctypes.py_object).value
时对应地址啥都没有,print语句就不管用了,所以没输出
import ctypes
a = [1,2,3,4]
print("最后一个元素(4)的id是:", id(a[-1]))
address1 = id(a[-1])
get_value1 = ctypes.cast(address1, ctypes.py_object).value # 读取地址中的变量
print("测试我们通过地址取值的有效性:",get_value1)
address = address1 + 32*(254)
get_value = ctypes.cast(address, ctypes.py_object).value # 读取地址中的变量
print("整数4的地址往后移动32位存放的值是:")
print(get_value)
输出
最后一个元素(4)的id是: 8791254619264
测试我们通过地址取值的有效性: 4
整数4的地址往后移动32位存放的值是: