liveBook · Manning

Scope

As explained in The Quick Python Book, Fourth Edition

A scope is a region of program execution in which name bindings can be resolved and accessed according to Python's lookup rules.

Scope determines which name binding Python uses at a particular point in a program. A namespace maps names to objects. A module, script, or interactive session has a namespace for its top-level names; each function call gets a local namespace of its own. section 10.7

For an ordinary name lookup, keep these rules in mind:

  • Python checks the local namespace first, then the global namespace, then built-ins. If the name is absent from all three, it raises NameError. section 10.7
  • Parameters and names assigned inside a function are local to that call. A function’s global namespace belongs to its containing module, not to the code that called it. section 9.4 section 10.7
  • Use global to assign to a top-level binding. In a nested function, use nonlocal to assign to a previously bound name in the closest enclosing scope. section 9.4

A local assignment does not change a top-level name

Start with `a = "one"` and `b = "two"`. A function containing `global a; a = 1; b = 2` changes top-level `a` to `1`, but leaves top-level `b` as `"two"`. Its assignment to `b` creates a local binding. section 9.4

Listing 9.1 File nonlocal.py
g_var = 0                                                        #1
nl_var = 0                                                       #2
print("top level-> g_var: {0} nl_var: {1}".format(g_var, nl_var))
def test():
    nl_var = 2                                                   #3
    print("in test-> g_var: {0} nl_var: {1}".format(g_var, nl_var))
    def inner_test():
 
        global g_var                                             #4
        nonlocal nl_var                                          #5
        g_var = 1
        nl_var = 4
        print("in inner_test-> g_var: {0} nl_var: {1}".format(g_var,
                                                              nl_var))
        
    inner_test()
    print("in test-> g_var: {0} nl_var: {1}".format(g_var, nl_var))
 
test()
print("top level-> g_var: {0} nl_var: {1}".format(g_var, nl_var))

Run the nested-function example alongside its printed output: `global g_var` changes the top-level binding, while `nonlocal nl_var` changes the binding in `test()`, leaving the top-level `nl_var` unchanged. section 9.4

Scope also explains two practical surprises. Assigning `list = [1, 3, 5, 7]` hides the built-in `list` at that level; `del list` removes that binding and restores access. And a name defined in an imported module is normally accessed through that module, rather than becoming a top-level name in the importing script. When a name seems wrong or missing, inspect `locals()`, `globals()`, or `dir()`. section 10.7.1 section 10.9

How The Quick Python Book, Fourth Edition covers it

How deep it goes
Explains namespace lookup, per-call locals, and global and nonlocal assignments, while deferring further namespace detail to standard-library documentation.
Examples
Contrasts local and global assignments, traces nested-function bindings, and shows a built-in hidden by an assignment.
What it assumes
Assumes familiarity with function definitions, arguments, and parameters in another language; introduces Python namespaces and lookup rules directly.
What you can do after
Diagnose/debug missing or unexpected names with locals(), globals(), and dir(), and choose global or nonlocal for intended assignments.
How it connects
Connects namespaces, function parameters, modules, built-ins, global and nonlocal statements, and NameError.

Also explained in

Compare how 21 books explain scope →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Quick Python Book, Fourth Edition. The section links point to the parts of the book it draws on.