Python内部的Integer Cache是怎么回事?

Python内部的Integer Cache是怎么回事?

在深入研究Python的源代码之后,我发现它维护了一个PyInt_Objects范围从int(-5)到int(256)(@src/objects/intopject.c)

一个小实验证明了这一点:

>>> a = 1>>> b = 1>>> a is bTrue>>> a = 257>>> b = 257>>> a is bFalse

但是,如果我在py文件中一起运行这些代码(或者用分号连接它们),结果就不一样了:

>>> a = 257; b = 257; a is bTrue

我很好奇为什么它们仍然是同一个对象,所以我深入到语法树和编译器中,我想出了下面列出的调用层次结构:

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 = 257b = 257print "id(a) = %d, id(b) = %d" % (id(a), id(b))

输出结果如下:

DEBUG: before PyAST_FromNodename = a
ival = 257, id = 176046536name = b
ival = 257, id = 176046752name = a
name = b
DEBUG: after PyAST_FromNoderun_modPyAST_Compile ok
id(a) = 176046536, id(b) = 176046536Eval ok

意思是在cstast变换,两种不同PyInt_ObjectS被创建(实际上它是在ast_for_atom()函数),但它们后来被合并。

我觉得很难理解PyAST_CompilePyEval_EvalCode所以我是来寻求帮助的,如果有人给我提示的话,我会很感激的?


慕的地6264312
浏览 384回答 1
1回答
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python