@

目录

  • python的整数重用机制
  • small_ints
  • 代码块
  • 问题一:为什么在vscode中运行代码,得到了不符的结果?
  • 问题二:在问题一存在的基础上,为什么能测得[-5,256]这一范围?
  • 其他图片
  • vscode已安装的扩展
  • settings.json
  • 后语
  • 附带ID为“发霉的宅大人”帮忙提供的版本相关源码
  • 2021-1-4
  • 2021-1-5
  • 新的问题
  • 2021-1-7

python的整数重用机制

大体可以分为两部分:

small_ints

链表small_ints内保存着一定范围的小整数。当有变量引用了范围内的整数时,就会直接引用此中的地址,而非开辟新地址来存储数据。
这一范围可以通过下列代码来查看:

z = []
for i in range(-1000, 1000):
    for j in range(-1000, 1000):
        if id(i) == id(j):
            z.append(i)
print([z[0], z[-1]])

python3.8.3得出的结果是[-5,256]。
也就是说,当以‘=’形式来给变量a、b赋范围内值时,id(a)==id(b)。

代码块

代码块是程序的一个最小的基本执行单位,一个模块文件、一个函数体、一个类、交互式命令中的单行代码都叫做一个代码块。
Python内部为了进一步提高性能,凡是在一个代码块中创建的整数对象,如果值不在small_ints缓存范围之内,但在同一个代码块中已经存在一个值与其相同的整数对象了,那么就直接引用该对象,否则创建一个新的对象出来。
需要注意的是,在small_ints范围外的负数并不适用这一规则。(范围内的负数浮点数同样不适用)


问题一:为什么在vscode中运行代码,得到了不符的结果?

Python整数统计 整数用python_缓存


Python整数统计 整数用python_Python整数统计_02


下面放一张全图

Python整数统计 整数用python_python_03

问题二:在问题一存在的基础上,为什么能测得[-5,256]这一范围?

Python整数统计 整数用python_Python整数统计_04


其他图片

vscode已安装的扩展

Python整数统计 整数用python_代码块_05

settings.json

Python整数统计 整数用python_python_06

后语

之前接触到整数缓存时曾做过测试,的确与介绍相符。但是,近期却发现自己测试出了相反的结果,一直不明白哪里出了问题,因此发到网上来。如有人能指出,不胜感激。

附带ID为“发霉的宅大人”帮忙提供的版本相关源码

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif
static PyObject *
get_small_int(sdigit ival)
{
    PyObject *v;
    assert(-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS);
    v = (PyObject *)&small_ints[ival + NSMALLNEGINTS];
    Py_INCREF(v);
#ifdef COUNT_ALLOCS
    if (ival >= 0)
        _Py_quick_int_allocs++;
    else
        _Py_quick_neg_int_allocs++;
#endif
    return v;
}

2021-1-4

昨天卸载并重新安装了新版本的python、vscode,情况依旧没有改变。

Python整数统计 整数用python_Python整数统计_07


测试小整数缓存表范围,ok(与之前一样)。

Python整数统计 整数用python_代码块_08


测试256地址,在不同代码块内保持一致,但每次都不一样。

Python整数统计 整数用python_代码块_09


测试-6地址,每次都不一样,但在不同代码块内保持一致。

2021-1-5

在“发霉的宅大人”的建议下,使用IDLE进行测试,以下为测试结果:

Python整数统计 整数用python_python_10


Python整数统计 整数用python_python_11


Python整数统计 整数用python_代码块_12


Python整数统计 整数用python_Python整数统计_13


使用python解释器进行测试(不懂得怎么在定义函数时换行,暂时没找到教程,因此使用时尝试了多次,代码格式有没有问题……),以下为测试结果:

Python整数统计 整数用python_缓存_14


显然,256在不同代码块处于相同的地址中,而257则在不同代码中呈现出了两处地址。这对我来说无疑是个好消息。我曾以为,python中的小整数缓存表都存储在固定的地址之中。在直接使用python解释器运行代码没问题的情况下,我重新取得了256的地址:

Python整数统计 整数用python_代码块_15


256的地址和上面256的地址并不相同,看样子python会在每次代码运行前为处于[-5,256]区间的小整数重新分配地址。

新的问题

将上述问题综合一下,本文的主要问题变成:
“为什么vscode、IDLE二者和python解释器运行同一代码会出现不同的结果?是什么导致了这一区别?”

2021-1-7

Python整数统计 整数用python_python_16


Python整数统计 整数用python_代码块_17