首页 > 后端开发 > Python教程 > 为什么 Python 的整数缓存行为会根据代码的执行方式而变化?

为什么 Python 的整数缓存行为会根据代码的执行方式而变化?

Patricia Arquette
发布: 2024-12-20 02:34:13
原创
246 人浏览过

Why Does Python's Integer Cache Behavior Change Depending on How the Code is Executed?

解释器维护的整数缓存是怎么回事?

在探索 Python 的源代码后,我发现了一个维护的 PyInt_Object 数组,范围从 int(- 5) 到 int(256) (@src/Objects/intobject.c).

运行一个小测试证明了这一点:

>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False
登录后复制

但是,当在 py 文件中一起运行这些命令时或者用分号连接它们,结果更改:

>>> a = 257; b = 257; a is b
True
登录后复制

为了理解为什么这两个整数仍然引用同一个对象,我深入研究了语法树和编译器,并发现了以下调用层次结构:

PyRun_FileExFlags()
mod = PyParser_ASTFromFile()
    node *n = PyParser_ParseFileFlagsEx() //source to cst
        parsetoke()
            ps = PyParser_New()
            for (;;)
                PyTokenizer_Get()
                PyParser_AddToken(ps, ...)
mod = PyAST_FromNode(n, ...)  //cst to ast
run_mod(mod, ...)
    co = PyAST_Compile(mod, ...) //ast to CFG
        PyFuture_FromAST()
        PySymtable_Build()
        co = compiler_mod()
    PyEval_EvalCode(co, ...)
        PyEval_EvalCodeEx()
登录后复制

然后我将调试代码集成到 PyInt_FromLong 和 PyAST_FromNode 之前/之后,然后运行test.py 脚本:

a = 257
b = 257
print "id(a) = %d, id(b) = %d" % (id(a), id(b))
登录后复制

输出为:

DEBUG: before PyAST_FromNode
name = a
ival = 257, id = 176046536
name = b
ival = 257, id = 176046752
name = a
name = b
DEBUG: after PyAST_FromNode
run_mod
PyAST_Compile ok
id(a) = 176046536, id(b) = 176046536
Eval ok
登录后复制

这表明在 cst 期间生成了两个单独的 PyInt_Object到 ast 转换(在 ast_for_atom() 中执行);

我发现 PyAST_Compile 和 PyEval_EvalCode 中的源代码难以理解,因此我寻求帮助。有人可以提供任何见解吗?

以上是为什么 Python 的整数缓存行为会根据代码的执行方式而变化?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板