...

/

Evaluating Arbitrary Strings As Python Expressions

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.

Press + to interact
print (eval('1 + 1 == 2'))
#True
print (eval('1 + 1 == 3'))
#False
print (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.

Press + to interact
print (eval('"A" + "B"'))
#AB
print (eval('"MARK".translate({65: 79})'))
#MORK
print (eval('"AAAAA".count("A")'))
#5
print (eval('["*"] * 5'))
#['*', '*', '*', '*', '*']

But wait, that’s not all!

Press + to interact
x = 5
print (eval("x * 5")) #①
#25
print (eval("pow(x, 2)")) #②
#25
import math
print (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…

Press + to interact
import subprocess
print (eval("subprocess.getoutput('ls ~')")) #①
#ls: cannot access /nonexistent: No such file or directory
print (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 ...