Co zawiera pamięć podręczna Integer w Pythonie?
Po nurkowaniu w kodzie źródłowym Pythona stwierdzam, że utrzymuje on tablicęPyInt_Object
s od int (-5) do int (256) (@ src / Objects / intobject.c)
Mały eksperyment to potwierdza:
>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False
Ale jeśli uruchomię te kody razem w pliku py (lub połączę je średnikami), wynik będzie inny:
>>> a = 257; b = 257; a is b
True
Ciekawe, dlaczego wciąż są tym samym obiektem, więc zagłębiam się głębiej w drzewo składniowe i kompilator, wymyśliłem hierarchię wywołań wymienioną poniżej:
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()
Następnie dodałem kod debugowaniaPyInt_FromLong
i przed / poPyAST_FromNode
i wykonał test.py:
a = 257
b = 257
print "id(a) = %d, id(b) = %d" % (id(a), id(b))
wyjście wygląda tak:
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
Oznacza to, że podczascst
doast
przekształcić, dwa różnePyInt_Object
s są tworzone (w rzeczywistości są wykonywane wast_for_atom()
funkcji), ale później są scalane.
Trudno mi zrozumieć źródło wPyAST_Compile
iPyEval_EvalCode
, więc jestem tutaj, aby poprosić o pomoc, będę wdzięczny, jeśli ktoś daje podpowiedź?