Aller au contenu

Compiler et exécuter du code dynamiquement

Ces fonctions répondent à des besoins avancés, comme certains outils d'analyse ou environnements interactifs. Le code fourni doit être maîtrisé : eval() et exec() peuvent exécuter des opérations arbitraires. Elles ne doivent pas recevoir directement une saisie non fiable.

compile() : préparer du code

compile() transforme une source en objet code, sans exécuter ce code dans l'usage présenté ici. Le nom de fichier sert notamment aux diagnostics.

code = compile("10 + 20", "<calculation>", "eval")
print(eval(code))  # 30

Les modes principaux sont eval pour une expression, exec pour une suite d'instructions et single pour une instruction interactive.

Equivalent en C#

Expression<Func<int>> expression = () => 10 + 20;
Func<int> calculation = expression.Compile();
Console.WriteLine(calculation()); // 30

Expression.Compile() compile un arbre d’expression déjà construit ; elle n’analyse pas une chaîne de code C#. Ce rapprochement illustre seulement la préparation d’un calcul exécutable. Compiler une source C# à l’exécution exige d’autres outils, par exemple les packages Roslyn, non ajoutés ici.

eval() : évaluer une expression

context = {"price": 100, "tax_rate": 0.20}
result = eval("price * (1 + tax_rate)", context)
print(result)  # 120.0

Pour cet exemple, un calcul direct serait préférable. Fournir un dictionnaire de contexte, même en limitant les fonctions natives, ne transforme pas eval() en environnement sécurisé.

Equivalent en C#

double price = 100;
double taxRate = 0.20;
Func<double> calculation = () => price * (1 + taxRate);
Console.WriteLine(calculation()); // 120

C# ne possède pas d’eval() natif évaluant une chaîne de code général. Un délégué exprime ici le calcul connu. Le mot-clé dynamic ne compile pas une chaîne ; le scripting C# requiert un outil distinct. L’exemple ne prétend donc pas reproduire l’évaluation textuelle Python.

exec() : exécuter des instructions

exec() exécute du code et renvoie None. Un dictionnaire explicite permet de récupérer les noms créés.

namespace = {}
exec("total = 10 + 20", namespace)
print(namespace["total"])  # 30

Equivalent en C#

var state = new Dictionary<string, int>();
Action operation = () => state["total"] = 10 + 20;
operation();
Console.WriteLine(state["total"]); // 30

Il n’existe pas d’équivalent C# natif de exec() pour exécuter une chaîne. Ce délégué réalise l’action prévue avec un état explicite. Pour une source dynamique, une solution de compilation ou de scripting serait nécessaire, avec son propre modèle de confiance.