Evaluating Arbitrary Strings As Python Expressions
We'll cover the following...
This is the final piece of the puzzle (or rather, the final piece of the puzzle solver). After all that fancy string manipulation, we’re left with a string like '9567 + 1085 == 10652'
. But that’s a string, and what good is a string? Enter eval()
, the universal Python evaluation tool.
print (eval('1 + 1 == 2'))#Trueprint (eval('1 + 1 == 3'))#Falseprint (eval('9567 + 1085 == 10652'))#True
But wait, there’s more! The eval()
function isn’t limited to boolean expressions. It can handle any Python expression and returns any datatype.
print (eval('"A" + "B"'))#ABprint (eval('"MARK".translate({65: 79})'))#MORKprint (eval('"AAAAA".count("A")'))#5print (eval('["*"] * 5'))#['*', '*', '*', '*', '*']
But wait, that’s not all!
x = 5print (eval("x * 5")) #①#25print (eval("pow(x, 2)")) #②#25import mathprint (eval("math.sqrt(x)")) #③#2.23606797749979
① The expression that eval()
takes can reference global variables defined outside the eval()
. If called within a function, it can reference local variables too.
② And functions.
③ And modules.
Hey, wait a minute…
import subprocessprint (eval("subprocess.getoutput('ls ~')")) #①#ls: cannot access /nonexistent: No such file or directoryprint (eval("subprocess.getoutput('rm /some/random/file')")) #②#rm: cannot remove '/some/random/file': No such file or directory
① The subprocess
module allows you to run arbitrary shell commands and get the result as a Python string.
② Arbitrary shell commands can have permanent consequences.
It’s even worse than that, because there’s a global __import__()
function ...