Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

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.