1

I'd like to be able to evaluate arbitrary code from a string in Python, including code composed of multiple statements, and statements that span multiple lines. The approaches I've tried so far have been to use exec and eval, but these seem to only be able to evaluate expressions. I have also tried the code.InteractiveInterpreter class, but this also only seems to allow evaluation using eval, exec, or single-statement modes. I've tried splitting the code by line, but this fails to handle statements that span multiple lines. Is there a way to accomplish this?

jbeard4
  • 12,664
  • 4
  • 57
  • 67
  • 1
    No you don't want this. Because it's completely unneeded, unsafe, adds a lot of headache and is dirty anyway. –  May 31 '11 at 16:43
  • 1
    @delnan: He's not said what he's working on. There's no harm in a warning about it, but maybe he does actually want this? – Thomas K May 31 '11 at 16:55
  • @Thomas: There are cases where this (with ecxessive attention on validation and/or sandboxing, of course) is a valid approach. But they're rare and for some reason relatively many people try to use this for problems that have much better solutions. So *chances* are this is one of those cases. –  May 31 '11 at 17:06
  • 3
    @delnan: Let's give people the benefit of the doubt, at least until we know the reasoning. Anyway, it's only really unsafe in a server/client model where you have to defend against possible malicious users. If it's a program running on the user's own computer, they're free to 'hack' it. – Thomas K May 31 '11 at 17:41

4 Answers4

3

exec seems to be what you are looking for:

s = """
for i in range(5):
    print(i)
"""
exec s

prints

0
1
2
3
4

eval() only handles expressions, but exec handles arbitrary code.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
3

Can you tell me the issue you're facing with exec? This seems to work for me.

>>> foo = """
... def baz():
...   print "Hello"
... """
>>> 
>>> exec foo
>>> baz()
Hello
>>> 

exec also has an in form where you can insert the result of the evaluation into a namespace which is better than polluting the current one.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
2

Just to build on what sven is saying there is a conditional part to using exec which allows the specification of a namespace to execute inside for example when exec code in the global namespace you can do

exec "code" in globals()

or if you want to specify your own namespace hand it a dict

di = {}
exec "code" in di
Jakob Bowyer
  • 33,878
  • 8
  • 76
  • 91
0

Update for Python 3: Just as with print, exec now has to be used with parenthesis:

exec("print(1)")

Some things have changed in the behavior, see this thread

Thomas
  • 4,696
  • 5
  • 36
  • 71