How to Execute a String Containing Python Code in Python

How do I execute a string containing Python code in Python?

In the example a string is executed as code using the exec function.

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()

Execute a string as a command

You can use eval.eval() is used to evaluate expression, If you want to execute a statement, use exec()

See example for eval:

def fun():
print "in fun"

eval("fun()")

x="fun()"
eval(x)

See example for exec.

exec("print 'hi'")

Executing a string as python code and storing output + errors

Try surrounding the execution code in a try/except block.

try:
exec(my_code)
except:
print("Unexpected error:", sys.exc_info()[0])
raise

Executing string of python code within bash script

You only have to redirect that here-string/document to python

python <<< "print('Hello')"

or

python <<EOF
print('Hello')
EOF

and encapsulate that in a function

execute_python_fragment() {
python <<< "$1"
}

and now you can do your

result=$(execute_python_fragment "${python_fragment}")

You should also add some kind of error control, input sanitizing... it's up to you the level of security you need in this function.

Running Python code contained in a string

You can use the eval(string) method to do this.

Definition

eval(code, globals=None, locals=None)

The code is just standard Python code - this means that it still needs to be properly indented.

The globals can have a custom __builtins__ defined, which could be useful for security purposes.

Example

eval("print('Hello')")

Would print hello to the console. You can also specify local and global variables for the code to use:

eval("print('Hello, %s'%name)", {}, {'name':'person-b'})

Security Concerns

Be careful, though. Any user input will be executed. Consider:

eval("import os;os.system('sudo rm -rf /')")

There are a number of ways around that. The easiest is to do something like:

eval("import os;...", {'os':None})

Which will throw an exception, rather than erasing your hard drive. While your program is desktop, this could be a problem if people redistributed scripts, which I imagine is intended.

Strange Example

Here's an example of using eval rather strangely:

def hello() : print('Hello')
def world() : print('world')
CURRENT_MOOD = 'happy'

eval(get_code(), {'contrivedExample':__main__}, {'hi':hello}.update(locals()))

What this does on the eval line is:

  1. Gives the current module another name (it becomes contrivedExample to the script). The consumer can call contrivedExample.hello() now.)
  2. It defines hi as pointing to hello
  3. It combined that dictionary with the list of current globals in the executing module.

FAIL

It turns out (thanks commenters!) that you actually need to use the exec statement. Big oops. The revised examples are as follows:


exec Definition

(This looks familiar!)
Exec is a statement:

exec "code" [in scope]
Where scope is a dictionary of both local and global variables. If this is not specified, it executes in the current scope.

The code is just standard Python code - this means that it still needs to be properly indented.

exec Example

exec "print('hello')"

Would print hello to the console. You can also specify local and global variables for the code to use:

eval "print('hello, '+name)" in {'name':'person-b'}

exec Security Concerns

Be careful, though. Any user input will be executed. Consider:

exec "import os;os.system('sudo rm -rf /')"

Print Statement

As also noted by commenters, print is a statement in all versions of Python prior to 3.0. In 2.6, the behaviour can be changed by typing from __future__ import print_statement. Otherwise, use:

print "hello"

Instead of :

print("hello")

How to convert a string to python code in python?

Yes, eval() only evaluates expressions, not statements or suites (which comprise full Python programs).

You're looking for the exec() function.

exec("for i in range(100):\n\tprint(i)")

However, do remember you usually don't need eval() or exec(), and especially you'll never want to exec() or eval() user input.

How can I convert string to source code in python?

You can use eval() function to evaluate Python source code.

Quoting the documentation:

eval(expression, globals=None, locals=None)

The arguments are a string and optional globals and locals. If provided, globals must be a dictionary. If provided, locals can be any mapping object.

How to execute a string containing condition in python dataframe

eval is what you are looking for.

def func(df,cond1,cond2):
expression = eval(f"(df.A {cond1}) & (df.B{cond2})")

return df[expression]

Python: using eval to execute code in the string

You're looking for exec not eval:

code = """
if age > 18:
if salary > 100000:
print('success')
elif salary < 50000:
print('fail')
else:
print('get_more_info')
else:
print('fail')"""

exec(code, {"age": 20, "salary": 60000})
# out: get_more_info

exec takes a code string, or an code object. While eval takes an expression.


Alternatively, you can always evaluate (using eval) code objects by compiling the code string beforehand:

eval(compile(code, '<string>', 'exec'), {"age": 20, "salary": 60000})
# out: get_more_info

Just for the fun of it, you can use eval for your syntax tree without needing to compile your code, but your code has to be a bit different:

code = 'print(("success" if salary > 100000  else "fail" if salary < 50000 else "get_more_info") if age > 18 else "fail")'

eval(code, {"age": 20, "salary": 60000})
# out: get_more_info

This utilizes Python's ternary conditions, which technically is still counted as an expression.

How to execute a string containing a script using python subprocess module

This solution is based on -c (compile) Python interpreter cmdline argument. It ignores using shell properties entirely.

Popen may be created in similar way. subprocess.call was used to show that script is in fact executed, and python interpreter return code is changed by code executed.

import subprocess

executable_code = """
print 'inside script'
print 123
"""

code_with_exception = """
raise Exception()
"""

ok_rc = subprocess.call(['python', '-c', executable_code])
assert ok_rc == 0

bad_rc = subprocess.call(['python', '-c', code_with_exception])
assert bad_rc == 1

Additional improvement would be to skip 'python' hardcoded string and use sys.executable.

A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense. If Python is
unable to retrieve the real path to its executable, sys.executable
will be an empty string or None.

import sys
import subprocesss
code = "raise Exception()"
bad_rc = subprocess.call([sys.executable, '-c', code])
assert bad_rc == 1


Related Topics



Leave a reply



Submit