Binding and scope#

We touched on variable bindings in local and global scopes in Chapter 2. It is time to both review that material and take a deeper dive.

Aliasing#

We begin with a review of how variables are bound to objects containing values in name spaces. This time, we focus especially on the consequences of aliasing, when two variables are bound to the same object. This leads us to make an important distinction between mutable and immutable objects.

Scopes#

In Python (as in most programming languages), activation records reside as frames on a stack. Objects containing values, on the other hand, reside in the heap. Understanding stack allocation and heap allocation is fundamental to understanding functions in Python.

With this understanding of binding, frames in the stack, and objects in the heap containing values, we can describe more precisely what Python does when it encounters a variable name, including “qualified names” from other modules.

Imports and qualified names#

An import statement in Python is like a special kind of assignment, binding a module object to a name. A module object is a namespace where other names can be bound to values.

When we write a qualified name like a.b.c, we are asking Python to first find a, then look within a to find b, then look within b to find c. If a is a module that we have imported, and f and g are functions defined in the source code of a, then after importing a we can refer to those functions as a.f and a.g.

Binding and recursion#

Recursive functions follow the same scope rules as any other functions. We revisit the palindrome example from the previous chapter to illustrate how binding rules and stack allocation of activation records work together.