> Les bases > Le langage > Evaluation dynamique de code
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