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

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

Patricia Arquette
Patricia Arquette原创
2024-12-20 02:34:13249浏览

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn