Python Scopes – the places where variables are defined and looked up

It is essential to understand what names mean in Python. When you use a name in a program, Python creates, changes, or looks up the name in what is known as a namespace, a place where names live. The term “scope” refers to a namespace.

Names in Python begin to exist when they are first assigned values, and they must be assigned before they are used.

All names assigned inside a function are associated with that function’s namespace which means that names assigned inside a def can only be seen by the code within that def, they do not clash with variables outside the def (even if the same names are used; an a variable inside a def is different than an a variable outside the def).

The scope of a variable (where it can be used) is always determined by where it is assigned in your source code:

  • local variables – assigned inside a def
  • nonlocal to nested functions – assigned in an enclosing def
  • global variables – assigned outside all def

Note:
The terminal is a module named __main__ that prints results and doesn’t save its code; in all other ways it is like the top level of a module file.

Functions define a local scope and modules define a global scope with the following properties:

  • The enclosing module is a global scope. Each module is a global scope, a namespace in which variables created (assigned) at the top level of the module file live. Global variables become attributes of a module object to the outside world after imports but can also be used as simple variables within the module file itself.
  • The global scope spans a single file only. Names at the top level of a file are global to code within that file only.
  • Assigned names are local unless declared global or nonlocal.
  • All other names are enclosing function locals, globals, or built-ins.
  • Each call to a function creates a new local scope.

Code typed at the interactive command prompt (terminal) follows the normal scope rules. Any type of assignment within a function classifies a name as local. Changing an object is not an assignment to a name.

Example:

# Global Scope
>>> a = 4
>>> 
>>> def my_function(b):
…    # Local Scope
...     c = a + b
...     return c
... 
>>> my_function(3)
7

Our code has global names (a and my_function()). The a is global because it’s assigned at the top level of the module file. The my_function() is global for the same reason.
Our code also has local names. The b and c are local to the function (and exist only while the function runs) because they are both assigned values in the function definition: c by virtue of the = statement, and b because arguments are always passed by assignment.

In our example, the argument b and the result c exist only inside the function. Local variables are removed automatically from memory when the function call exits.

There is a built-in module called builtins, but it has to be imported. The builtins is implemented as a standard library module but that name itself is not placed in the built-in scope, so you have to import it in order to inspect it. Once you do, you can run a dir call to see which names are predefined.

>>> import builtins
>>> dir
<built-in function dir>
>>> dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 
…
'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']

Note:
Many names are omitted! Run the command for yourself to see the full list!

You ca use the builtins module by importing it or taking advantage of the LEGB rule (Python automatically searches this module last in its LEGB lookup).

Leave a Reply