Basic Usage
Here are additional resources about Python grammar:
00:00
In the previous lesson, I gave you a quick overview of the course. In this lesson, I’m going to talk about the basic usage of eval()
.
00:09
The built-in function eval()
can take a subset of the Python language known as an expression. Common expressions are things like doing math.
00:19
Here, I’m passing a string to eval()
that is a Python multiplication. eval()
takes the contents of it, parses it, compiles it, runs it as Python, and then returns the result.
00:32
Here’s another one using exponential. Same concept. You can also use functions. Because sum()
returns a value, the result of eval()
is the evaluation of that sum of the list of numbers.
00:48
eval()
also has access to the global namespace. I can create a variable here and then evaluate using that variable. There are ways of further restricting this, but I’ll show you those later.
01:01
Here’s the signature for eval()
. It takes an expression and optionally two dictionaries—one for globals, one for locals.
01:10 An expression is a subset of the Python language that includes literals, names, attributes, operations, or functions that return a value.
01:20
Let’s go over those one by one. A literal is data—things like an integer, a string, a float, a Boolean value, or even a list mixing these things. Names are variables, something that can be assigned. So in the statement x = 3
, x
is the name.
01:38
Note that x = 3
is a statement and not an expression. The assignment itself can’t be used in eval()
but the x
can be. Attributes are similar to names but instead of being global, they’re part of a named object.
01:51
If you had an object named part
with an attribute .serial_no
, you could access that inside of eval()
. Operations are expressions that combine literals with an operator. Common ones are things like math.
02:04
2 + 3
is a literal, operator, and a literal. This is together an expression. Similar with multiplication, subtraction, and even Boolean evaluation.
02:14
So value == result
is an expression. Finally, you can also use any function that returns a value. You can write one for Fibonacci, you can use functions from the math
library, or methods from your objects as long as they return something. Those were expressions.
02:32
What’s not an expression? Well, for starters, assignment. eval()
won’t take "x = 100"
. That’s a statement. Statements aren’t allowed.
02:42
It raises a SyntaxError
and indicates what the problem is—in this case, the operation of assignment, the equals (=
).
02:52
If I want to use x
, I have to do it outside of eval()
. Conditionals that are usually multiline—those with colons (:
) in them—are also statements.
03:03
This is also considered a SyntaxError
. Invalid expressions also cause problems. Technically this isn’t a statement but if I haven’t finished the expression, it will also cause a SyntaxError
.
03:17
So, here are things that aren’t expressions. Like I showed you in the example, assignments are statements. Conditionals and import
also is considered a statement.
03:28
This means if you want to use something like the math
library inside of eval()
, you’ll have to do the import outside of the eval()
call.
03:37
Any looping structures like for
and while
are also considered statements. And finally, any sort of exceptions—try
, catch
, raise
, et cetera.
03:47
The eval()
method has a cousin called exec()
. The signature is very similar to the eval()
. Unlike eval()
, exec()
will run any kind of code—statements and expressions included, so it’s the superset. Unlike eval()
, exec()
has no return result.
04:03
Even if the contents of the exec()
are a function call that returns something, exec()
itself will not return a result. These two built-in functions have similar purposes—running code—but slightly subtle different calling structures, so you can do different kinds of things with them.
04:19
This course concentrates on eval()
. I just thought I’d point out exec()
so that you were aware it was there if you want to go and play with it.
04:28
I’m going to spend a little time going off on a tangent here. I want to talk a little more about expressions and statements inside of Python. What I’ve covered so far is good enough for your understanding moving forward with eval()
.
04:39 If you’re bored by the details of the compiler and how parsers work, feel free to skip on to the next lesson. Otherwise, hang on and I’ll show you some deep-dive stuff in the language of Python.
04:50 The syntax of a programming language is specified by something called its grammar. In Python 3.9, a new kind of parser was introduced in order to take advantage of a more flexible grammar.
05:01 This parser is called a PEG parser, for Parsing Expression Grammar. So far, nothing new has been introduced to the language that couldn’t be done using the old-style grammar.
05:11 3.9 is a transition. And the concepts that I’m going to show you also exist inside of earlier versions, they’re just notated differently. A grammar specification indicates to a language how to parse the code file.
05:26 You can find the full specification for Python’s grammar at this URL. In the following few slides, I’m going to highlight a few key parts of the PEG and show you the differences between expressions and statements inside of the grammar specification.
05:44 Grammars aren’t specified themselves in Python. The language here that specifies the grammar is specific to the PEG. A common language for specifying coding grammars is something called BNF, Backus–Naur form. Prior to Python 3.9, Python used something called the EBNF, the extended Backus–Naur form.
06:05 A PEG grammar introduces a couple of new pieces, and so what’s being presented here is a hybrid of EBNF and PEG. The key thing to understand here is that it’s a recursive definition.
06:17
Everything shown in light blue is like the concept of a variable or a declaration. The third line down here defines something specific for eval()
in the grammar, saying that it will take expressions as well as newlines and endmarkers.
06:33
Compare that to the line above it, which is interactive, like the REPL, which takes a statement. So already here at the beginning of the PEG, you can see that the language breaks down into this concept of expressions and statements. Further down in the grammar, you’ll find the definition of expressions
.
06:51
It’s a compound one based on the definition of expression
, singular, and expression
can be combined with other expression
declarations to create the plural. Below that is the definition of the singular expression
.
07:06
It can be comprised of a lambda, a disjunction, or a conditional disjunction. The conditional disjunction is one where if
and else
is happening inside of the same line without a colon. These kinds of single-line conditionals aren’t that common in Python, so you may not have run into this before, but this would be something like x if y > 3 else y
.
07:31
That would return the value of x
if y
is greater than 3
, otherwise it would return the value of y
—all in a single line.
07:40
Continuing further into the grammar, you can see definitions for a disjunction
. The disjunction
is comprised of conjunctions. Conjunctions are comprised of inversions, inversions are comprised of inversions or comparisons, and this definition just keeps drilling down. Further down, you get into the concept of terms. Moving on, you’ll see that a term
consists of a term
and certain kinds of operators.
08:08
This is where you can start seeing things like multiplication and division. At the base of all this is the concept of an atom
. The atoms are the things that are actually parsed out.
08:19
These are things like text inside of your file that are keywords. Booleans—True
, False
—the None
placeholder, literals like numbers, lists, tuples, dictionaries—all those things that I described earlier that can be used inside of an expression inside of eval()
.
08:37 So think back to a couple of slides ago where the definition of an expression consisted of disjunctions, disjunctions of conjunctions, and all this moves down.
08:46 Because this is recursive, once you combine all those concepts, you’ll have some mix of atoms and operators, which result in the expressions that I’ve shown you so far.
08:57
By contrast to expressions, let’s look at the definition of an assignment
. There’s a lot going on here. I don’t want to go into every last little piece, but you can see that the assignment
is comprised of names, expressions, and then other kinds of sub-components like single_target
.
09:13
There’s also a definition for augmented assignments, which are just assignments which also use things like the plus equals (+=
) operator.
09:22
Moving further into the grammar, you can find the definition of statements
. More recursion here. statements
plural consists of multiple statement
declarations.
09:31
The statement
declaration consists of compound_stmt
(compound statements) or simple_stmt
(simple statements). simple_stmt
consists of small_stmt
(small statements) and some punctuation to go off with that. Digging into small_stmt
, and you’re starting to see things here that actually feel familiar to a Python programmer. A small_stmt
can be an assignment
, a star_expression
, a return_stmt
(return statement), an import_stmt
(import statement), raise
, pass
, del
(delete), yield
, assert
, break
, continue
, global
, or nonlocal
. Grammar further defines all of these concepts, but you get a sense here that the small_stmt
is kind of like the atom
inside of the expression
.
10:13
Just like the atom
where you start to see components like literals and True
and False
that seem familiar from the programming language, the small_stmt
consists of declarations that also feel like things that you’re probably used to—returning and importing, et cetera.
10:29 If you’re interested in the PEG grammar or more details about how all of this stuff works, there are some further reading links inside of the description. For now, I just wanted to give you a rough taste as to how all these pieces fit together and a better feeling as to the difference between an expression and a statement.
10:48
Next up, I’ll show you more of the parameters for eval()
and how to take advantage of them.
Become a Member to join the conversation.