Online Book Reader

Home Category

Learning Python - Mark Lutz [306]

By Root 1524 0
object from which to fetch the specified names. The LEGB rule applies only to bare, unqualified names. Here are the rules:

Simple variables

X means search for the name X in the current scopes (following the LEGB rule).

Qualification

X.Y means find X in the current scopes, then search for the attribute Y in the object X (not in scopes).

Qualification paths

X.Y.Z means look up the name Y in the object X, then look up Z in the object X.Y.

Generality

Qualification works on all objects with attributes: modules, classes, C extension types, etc.

In Part VI, we’ll see that qualification means a bit more for classes (it’s also the place where something called inheritance happens), but in general, the rules outlined here apply to all names in Python.

Imports Versus Scopes

As we’ve learned, it is never possible to access names defined in another module file without first importing that file. That is, you never automatically get to see names in another file, regardless of the structure of imports or function calls in your program. A variable’s meaning is always determined by the locations of assignments in your source code, and attributes are always requested of an object explicitly.

For example, consider the following two simple modules. The first, moda.py, defines a variable X global to code in its file only, along with a function that changes the global X in this file:

X = 88 # My X: global to this file only

def f():

global X # Change this file's X

X = 99 # Cannot see names in other modules

The second module, modb.py, defines its own global variable X and imports and calls the function in the first module:

X = 11 # My X: global to this file only

import moda # Gain access to names in moda

moda.f() # Sets moda.X, not this file's X

print(X, moda.X)

When run, moda.f changes the X in moda, not the X in modb. The global scope for moda.f is always the file enclosing it, regardless of which module it is ultimately called from:

% python modb.py

11 99

In other words, import operations never give upward visibility to code in imported files—an imported file cannot see names in the importing file. More formally:

Functions can never see names in other functions, unless they are physically enclosing.

Module code can never see names in other modules, unless they are explicitly imported.

Such behavior is part of the lexical scoping notion—in Python, the scopes surrounding a piece of code are completely determined by the code’s physical position in your file. Scopes are never influenced by function calls or module imports.[51]

Namespace Nesting

In some sense, although imports do not nest namespaces upward, they do nest downward. Using attribute qualification paths, it’s possible to descend into arbitrarily nested modules and access their attributes. For example, consider the next three files. mod3.py defines a single global name and attribute by assignment:

X = 3

mod2.py in turn defines its own X, then imports mod3 and uses qualification to access the imported module’s attribute:

X = 2

import mod3

print(X, end=' ') # My global X

print(mod3.X) # mod3's X

mod1.py also defines its own X, then imports mod2, and fetches attributes in both the first and second files:

X = 1

import mod2

print(X, end=' ') # My global X

print(mod2.X, end=' ') # mod2's X

print(mod2.mod3.X) # Nested mod3's X

Really, when mod1 imports mod2 here, it sets up a two-level namespace nesting. By using the path of names mod2.mod3.X, it can descend into mod3, which is nested in the imported mod2. The net effect is that mod1 can see the Xs in all three files, and hence has access to all three global scopes:

% python mod1.py

2 3

1 2 3

The reverse, however, is not true: mod3 cannot see names in mod2, and mod2 cannot see names in mod1. This example may be easier to grasp if you don’t think in terms of namespaces and scopes, but instead focus on the objects involved. Within mod1, mod2 is just a name that refers to an object with attributes, some of which may refer to other objects with attributes

Return Main Page Previous Page Next Page

®Online Book Reader