429 votes

Comment exécuter une chaîne contenant du code Python en Python ?

Comment exécuter une chaîne contenant du code Python en Python ?

6 votes

Pour être honnête, contrairement à l'autre question, celle-ci n'est pas un doublon. Et d'autres ont posté des questions beaucoup plus basiques que celle-ci.

11 votes

La réponse correcte, bien sûr, est presque toujours "ne le faites pas !".

24 votes

@S. Lott : Vous n'avez pas lu la FAQ récemment ? "Vous pouvez aussi parfaitement poser votre propre question de programmation et y répondre, mais faites comme si vous étiez à Jeopardy : formulez-la sous la forme d'une question". Ce n'est pas une mauvaise question. +1

406voto

Brian Points 48423

Pour les déclarations, utilisez exec(string) (Python 2/3) ou exec string (Python 2) :

>>> mycode = 'print "hello world"'
>>> exec(mycode)
Hello world

Lorsque vous avez besoin de la valeur d'une expression, utilisez eval(string) :

>>> x = eval("2+2")
>>> x
4

Cependant, la première étape devrait être de se demander si vous en avez vraiment besoin. L'exécution du code devrait généralement être la position de dernier recours : Il est lent, laid et dangereux s'il peut contenir du code saisi par l'utilisateur. Vous devriez toujours commencer par envisager des alternatives, telles que des fonctions d'ordre supérieur, pour voir si elles peuvent mieux répondre à vos besoins.

1 votes

Mais qu'en est-il de la portée du code exécuté par 'exec' ? est-il imbriqué ?

24 votes

Un cas courant où quelqu'un veut utiliser "exec" est quelque chose comme if s=='foo': x.foo = 42 elif s=='bar': x.bar = 42 etc., qu'ils peuvent ensuite écrire sous la forme exec ("x.%s = 42" % s) . Pour ce cas courant (où vous avez seulement besoin d'accéder à l'attribut d'un objet qui est stocké dans une chaîne de caractères), il existe une fonction beaucoup plus rapide, plus propre et plus sûre getattr : écrivez simplement getattr(x, s) = 42 pour signifier la même chose.

6 votes

En quoi exec est-il plus lent que l'interpréteur python ?

80voto

hekevintran Points 3000

Dans l'exemple, une chaîne de caractères est exécutée en tant que code à l'aide de la fonction exec.

import sys
import StringIO

# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()

code = """
def f(x):
    x = x + 1
    return x

print 'This is my output.'
"""

# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr

exec code

# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__

print f(4)

s = codeErr.getvalue()

print "error:\n%s\n" % s

s = codeOut.getvalue()

print "output:\n%s" % s

codeOut.close()
codeErr.close()

2 votes

Échanger stdout et stderr comme ça me rend très nerveux. cela semble pouvoir causer d'énormes problèmes de sécurité. y a-t-il un moyen de contourner cela ?

3 votes

@Narcolapser vous devriez vous préoccuper davantage d'utiliser exec du tout (sauf si vous connaître la chaîne de code provient d'une source fiable).

22voto

bheks Points 71

Rappelez-vous qu'à partir de la version 3 exec est une fonction !
donc toujours utiliser exec(mystring) au lieu de exec mystring .

13voto

LGB Points 59

eval() est juste pour les expressions, tandis que eval('x+1') travaux, eval('x=1') ne fonctionnera pas, par exemple. Dans ce cas, il est préférable d'utiliser exec ou encore mieux : essayez de trouver une meilleure solution :)

10voto

gus Points 51

Vous effectuez l'exécution du code en utilisant exec, comme dans la session IDLE suivante :

>>> kw = {}
>>> exec( "ret = 4" ) in kw
>>> kw['ret']

4

3 votes

Cela ne fonctionne pas en python normal. Du moins pas en python 3.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X