Что с Integer Cache внутри Python?

После погружения в 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 вast преобразовать, два разныхPyInt_Objects созданы (на самом деле это 'выполнено вast_for_atom() функции), но они позже объединены.

Мне трудно понять источник вPyAST_Compile а такжеPyEval_EvalCode, так что я'Я здесь, чтобы попросить о помощи, ябуду признателен, если кто-нибудь даст подсказку?

Ответы на вопрос(1)

Ваш ответ на вопрос