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意思是在cst到ast变换,两种不同PyInt_ObjectS被创建(实际上它是在ast_for_atom()函数),但它们后来被合并。我觉得很难理解PyAST_Compile和PyEval_EvalCode所以我是来寻求帮助的,如果有人给我提示的话,我会很感激的?
添加回答
举报
0/150
提交
取消