Python uses a namespace to allow identifiers to persist during evaluation.
A namespace associates each name that
appears in a Python expression with the object that it is bound to.
Thus the len identifier is associated or bound to a function object.
A namespace is like a dictionary, except instead of looking up a word and finding
a definition, the interpreter looks up a name and finds the object it is bound to.
This step is called dereferencing.
Dereferencing is the act of translating an identifier into
the memory object it is bound to during Python code evaluation.
This process is like looking for a restaurant name online.
You enter the name of the restaurant in your browser or app, and
you are given its location, which you use to find the restaurant in the real world.
When we open a Python shell, or run a Python program, the interpreter creates
a namespace and pre-binds many identifiers before evaluating our code.
For example,
the interpreter creates a function object that computes the length of a sequence.
It then adds the name len to the namespace, and
binds this name to the function object.
The interpreter pre-binds the names of all the built in functions.
For example, it binds the id and type function names as well.
If the names of he built in functions weren't pre-bound,
we would have no way to refer to them, so we could not use them.
The interpreter also pre-binds the name of each built in type to
a type object, and pre-binds many other identifiers as well.
You can use the built in function dir to see all of the built-in identifiers.
Notice the built-in function names len and
id, and the built-in type names str, int and float.
Also notice the names of some familiar errors, such as SyntaxError and NameError.
In our diagrams, we won't show all of the pre-bound identifiers,
we will only show the pre-bound names that we will use for
a particular Python shell example or program.
Here are the semantics of an identifier expression.
If the identifier is in the namespace,
dereference it to get the result object, otherwise report an error.
For example, if we evaluate an expression containing the identifier len,
the interpreter finds len in the namespace and
dereferences it to obtain the function object.
Let's evaluate an identifier hello that is not in the namespace.
This expression contains one token, the identifier hello.
The interpreter applies a semantic rule for identifier expressions.
It checks if the identifier hello is in the namespace.
Since hello is not prebound to a built-in function, type, or
any other kind of object, it is not in the namespace.
The interpreter reports a semantic error.
Since there is no result object, only the error is displayed.
We will discuss how to bind identifiers that are not pre-bound in later lessons.
A name tag can be worn by one person, and then worn by a different person later.
For example,
while driving a bus a person may wear a driver name tag to represent their role.
When a different person replaces the first driver, the driver name tag
can be detached from the first person and used by the second person.
An identifier is like a name tag, since we will discover in a future lesson
that an identifier can be bound to different objects at different times.
However, an identifier in a namespace
cannot be bound to two different objects at the same time.
As an analogy, there cannot be two people with the same driver role on one bus.
There is only one driver name tag on the bus, and
it can only be attached to one person at a time.
This video introduced the Python programming language semantics for
literals and identifiers.
Python places identifiers in a namespace and
reuses them when multiple expressions are evaluated.