Maison >développement back-end >Tutoriel Python >Pourquoi le comportement du cache d'entiers de Python change-t-il en fonction de la manière dont le code est exécuté ?

Pourquoi le comportement du cache d'entiers de Python change-t-il en fonction de la manière dont le code est exécuté ?

Patricia Arquette
Patricia Arquetteoriginal
2024-12-20 02:34:13249parcourir

Why Does Python's Integer Cache Behavior Change Depending on How the Code is Executed?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn