想法来自于 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位存放的值是: