Compiling Expressions
00:00
In the previous lesson, I showed you more information about expressions that eval()
can use. In this lesson, I’m going to show you how to compile an expression.
00:10
Up until now, I’ve only been demonstrating how to pass a string into eval()
. You can also pass in a pre-compiled object. Pre-compiled objects are returned by the built-in compile()
function.
00:22
The three mandatory parameters to compile that you need are source
, filename
, and mode
. The source
is the code to compile.
00:30
This would be the same as the expression
that’s passed into eval()
in string mode. The filename
is used to indicate where the source code comes from. In the case of eval()
, you really don’t care, so you can pass in "<string>"
to tell it that it’s a string.
00:47
The mode
indicates how to compile. If you want to compile something that would be a valid expression that eval()
could take as a string, pass in "eval"
as the mode
.
01:00 So, here I go. Let me compile an expression.
01:06
This creates an object that is inside the code
variable. The expression being compiled is "2 + 3"
, and it has the indicator that this is a string and that it’s being compiled in "eval"
mode. Now I can pass that code
object into eval()
, and I get the result, no different than if I had passed the string into eval()
.
01:32
Similarly to using eval()
directly, if I pass in something that isn’t an expression or a invalid expression, I will get a SyntaxError
raised.
01:42
In addition to having the "eval"
mode, compile()
also supports the "exec"
mode.
01:52
The difference here is that it compiles in the same pattern as the exec()
function. This means it’s not just expressions, but statements as well that can be compiled. Interestingly enough, eval()
doesn’t actually care what the code was compiled with.
02:09
I can pass in a code
object and it will work.
02:14
If I pass in something that was compiled in "eval"
mode, eval()
will return a response just like if you put a string into eval()
.
02:21
If I pass in a code
object that was compiled with "exec"
, exec()
doesn’t return a result, so eval()
will return None
. Now that I have math
imported, I can compile something a little more complicated.
02:40
And as further proof that everything in Python is an object, even this code
is an object. One of the members of this object tells you what functions are compiled inside of it.
02:52
By looking at .co_names
, you can see the math
library is referenced. sin()
, cos()
, and 'pi
are all used.
02:59
This gives you the ability to introspect what has been passed in and compiled. Next up, I’ll delve into the security risks of using eval()
, how some people attempt to avoid it, and why that’s still a problem.
Become a Member to join the conversation.