Mis a jour le 2025-04-14, 12:10

Evaluation dynamique de code

Evaluation dynamique de code en python :
  • on peut évaluer directement une expression avec la fonction eval :
    • eval('1 + 2') donne 3.
    • eval('"a".upper() + "b"') donne Ab.
    • x = 1; eval('x + 7') donne 8.
  • eval produit une exception si l'expression donne une erreur : x = 'a'; eval(x + 1).
  • on peut donner à eval des contextes de variables globales et locales dans lesquelles il va faire l'évaluation :
    • x = 1; eval('x + 1', globals(), locals()) : fait l'évaluation dans les contextes normaux.
    • x = 1; eval('x + 1', {}, {}) : fait l'évaluation dans des contextes vides de toute variable, et donc cela va produire une erreur, car x n'est pas défini.
  • eval ne marche pas sur du code et pas une simple expression, comme par exemple : x = 1.
  • il faut alors faire :
    • myCode = compile('x = 1; y = "a"', '<string>', 'exec') : compilation du code pour création d'un objet de type code (produit une exception si non valide). La valeur <string> est conventionnelle, elle peut être une chaîne quelconque.
    • puis évaluation du code : eval(myCode) : les variables x et y se trouvent alors ici définies.
  • attention : si on définit comme cela une nouvelle variable dans une fonction, ça ne marche pas car python va la chercher dans les variables globales :
    def myFunc():
        code = compile('a = 1', '<string>', 'exec')
        eval(code)
        return a # a est non définie !
        
  • par contre, si on fait l'évaluation dans le contexte global, la variable est définie, mais de manière globale :
    def myFunc():
        code = compile('a = 1', '<string>', 'exec')
        eval(code, globals(), globals())
        return a
        
  • solution pour éviter cela :
    def myFunc():
        code = compile('a = 1 + b', '<string>', 'exec')
        myEnv = {'b': 2} # défini b dans le contexte.
        eval(code, myEnv) # b et a sont définies dans le contexte myEnv
        a = myEnv['a'] # et on récupère la variable a dans le contexte local
        return a
        
Vérifier l'existence d'une variable x :
  • 'x' in locals() : renvoie True uniquement s'il y a un variable locale x.
  • 'x' in globals() : renvoie True uniquement s'il y a un variable globale x.
  • donc, on peut faire : if 'x' in locals() or 'x' in globals() pour voir si la variable x existe.
Pour avoir la valeur d'une variable connaissant son nom, par exemple 'x' :
  • si c'est une variable globale : globals()['x']
  • si c'est une variable locale : locals()['x']
  • on peut aussi faire eval('x'), mais toujours faire attention à la chaîne évaluée. Elle peut contenir un bout de code très dangereux !
Si on a le nom d'une fonction dans la variable x = 'myFunc' qui se trouve dans le même fichier, on peut l'appeler en faisant simplement : globals()[x](...)

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert