Qu'est-ce que le cache d'entiers maintenu par l'interpréteur ?
Après avoir exploré le code source de Python, j'ai découvert un tableau de PyInt_Objects maintenus, allant de int(- 5) à int(256) (@src/Objects/intobject.c).
L'exécution d'un petit test le prouve :
>>> a = 1 >>> b = 1 >>> a is b True >>> a = 257 >>> b = 257 >>> a is b False
Cependant, lors de l'exécution de ces commandes ensemble dans un fichier py ou en les joignant par des points-virgules, le résultat change :
>>> a = 257; b = 257; a is b True
Pour comprendre pourquoi ces deux les entiers font toujours référence au même objet, j'ai fouillé dans l'arbre syntaxique et le compilateur et suis tombé sur la hiérarchie d'appel suivante :
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()
J'ai ensuite intégré le code de débogage dans PyInt_FromLong et avant/après PyAST_FromNode , puis j'ai exécuté un script test.py :
a = 257 b = 257 print "id(a) = %d, id(b) = %d" % (id(a), id(b))
La sortie is :
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
Cela indique que deux PyInt_Objects distincts sont générés lors de la transformation cst en ast (exécutée dans ast_for_atom()) ; cependant, ces objets sont ensuite fusionnés.
J'ai trouvé le code source dans PyAST_Compile et PyEval_EvalCode difficile à comprendre, j'ai donc demandé de l'aide. Quelqu'un peut-il donner des idées ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!