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:
- Gives the current module another name (it becomes
contrivedExample
to the script). The consumer can callcontrivedExample.hello()
now.) - It defines
hi
as pointing tohello
- 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
Flask View Return Error "View Function Did Not Return a Response"
Split String With Multiple Delimiters in Python
How to Step Through Python Code to Help Debug Issues
Parse Date String and Change Format
How Are Python'S Built in Dictionaries Implemented
Convert Python Dict into a Dataframe
How to Save and Load Cookies Using Python + Selenium Webdriver
What Is the _Del_ Method and How to Call It
How to Read CSV Data into a Record Array in Numpy
How to Plot Data from Multiple Two Column Text Files With Legends in Matplotlib
Flask View Raises Typeerror: 'Bool' Object Is Not Callable
How to Capture Sigint in Python
Is There a Standardized Method to Swap Two Variables in Python
What Is the Formal Difference Between "Print" and "Return"
How to Check If a String Is a Substring of Items in a List of Strings
How to Install Pip With Python 3
Django Csrf Check Failing With an Ajax Post Request
Append Existing Excel Sheet With New Dataframe Using Python Pandas