Python內部的Integer Cache是怎么回事?在深入研究Python的源代碼之后,我發(fā)現(xiàn)它維護了一個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,并執(zhí)行了一個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被創(chuàng)建(實際上它是在ast_for_atom()函數(shù)),但它們后來被合并。我覺得很難理解PyAST_Compile和PyEval_EvalCode所以我是來尋求幫助的,如果有人給我提示的話,我會很感激的?
Python內部的Integer Cache是怎么回事?
慕的地6264312
2019-06-13 14:46:47