Imported and Qualified Names

Contents

Imported and Qualified Names#

The LEGB rule for finding something by name applies to imported modules as well. A module, whether from a built-in Python library or a new source file we construct, is a kind of object with a name.
An import statement is like an assignment that gives it a binding in the current module.

import csv            # Now "csv" is the name of a module object

another_name = csv    # Legal, but not the best approach
print(another_name)
<module 'csv' from '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/csv.py'>

We don’t usually assign modules to variables, but the code above demonstrates that Python treats the name of an imported module just like any other name. If we did want to use another name for a module, Python provides an import ... as ... syntax:

import doctest as dt

print(dt)
<module 'doctest' from '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/doctest.py'>

A module you write yourself is treated just like library module that Python provides.

Qualified names#

A module is an object that can contain other objects, including functions and variables. When we write m.v, we are asking Python to find m, and then to look inside m to find v.

Suppose, for example, we have this source file exporter.py:

"""exporter.py.  This module is designed to be imported by importer.py.
Its "symbols"  (names of functions and variables) will be
visible as attributes of the module.
"""

STEP_SIZE = 5

def step(i: int) -> int:
    return i + STEP_SIZE

We might import it as a module in another source file, exporter.py:

"""importer.py.  Demonstration of referencing qualified names
from another module.
"""

import exporter

print(exporter.step(10))
exporter.STEP_SIZE = 20
print(exporter.step(10))

After the import statement in importer.py, exporter is the name of a module object that contains variables and functions.
When we write exporter.step(10) in importer.py, Python first looks for the name exporter (following the LEGB search order) and finds it in the global scope. It looks within the module object for step, and finds a function object that it can call. The step function in exporter.py uses the LEGB search order to find STEP_SIZE, but “global” in this case means “global to the same module that step is in”. It finds the variable STEP_SIZE variable bound to integer value 5.

Similarly the statement exporter.STEP_SIZE = 20 asks Python to look within the module object exporter to find STEP_SIZE. It finds a variable that can be bound to the new value 20. When we call exporter.step the second time, the step function again uses the LEGB order, and again finds STEP_SIZE in its own module (the “global” scope for that module), now bound to integer value 20.

>>> python3 06-binding/samples/importer.py
15
30