Scope ===== .. toctree:: :maxdepth: 1 Indices and tables ------------------ * :ref:`genindex` * :ref:`modindex` * :ref:`search` In Python, like many other languages, it is possible to define variables (names) at many different points in your code. Knowing the rules the interpreter will use for finding the correct variable to manipulate is important for producing bug free code. The rules aren't all that difficult and are summarized in this section. .. _section_heading-Basic Rules: Basic Rules ----------- Python has the concept of a code :term:`block`. There are several things that are considered code blocks, but, the most important ones are: * A :term:`module` (a file or package) * A function body * A class definition Variables (names) must be defined before they are referenced. Variables (names) have a scope over which they are visible. The scope of a variable depends on where it was created (i.e. in which block): * Variables (names) created at the :term:`module` level are **global** and can be seen by all code enclosed in that module. * Variables (names) created inside a :term:`block` are by default **local** to (i.e. only visible to) the code in that block and any blocks nested inside of it. .. todo:: Need to add a section in classes about the fact that names defined at the top of the class are not availabe to the class' methods by default (see last paragraph of `here `_. Must mark method with ``@classmethod``, put ``cls`` as the first parameter, and use ``cls.var_name`` to access. As a corollary to the first 2 items, :term:`module` level variables are therefore both global and local. * Variables (names) not defined in the :term:`block` in which they are used and which are also not global, are called **free variables**. In the code samples below, ``x`` is a free variable when used in :py:func:`bar`: >>> def foo(): >>> x = 3 >>> def bar(): >>> print(x) >>> bar() >>> foo() 3 Variables (names) are found (resolved) by finding the nearest enclosing scope that contains a variable (name) that matches (see `below `_ for details on how to modify this behavior). If a variable is not found, a :py:exc:`NameError` or :py:exc:`UnboundLocalError` is thrown by the interpreter. Pretty straight forward and sensible. But, lets look at some examples to help solidify things: In the code below, the variable ``x`` is defined at module level, therefore it is global and thus visible to all code, as shown with the highlighted lines. .. literalinclude:: scope_example0.py :linenos: :emphasize-lines: 2-20 In the code below, the variable ``y`` is defined within a function body, therefore it is local to that function body and is thus visible from it's point of declaration on-ward, including into any nested function bodies, as shown with the highlighted lines. .. literalinclude:: scope_example0.py :linenos: :emphasize-lines: 6-15 In the code below, the variable ``z`` is also defined in a function body, therefore it is local to that function body and is thus visible from it's point of declaration on-ward just like ``y`` was. However, in this example, there are no further nested functions. .. literalinclude:: scope_example0.py :linenos: :emphasize-lines: 10-11 We can also flip this around and look at it from the opposite direction by determining the list of scopes that are visible to a block of code. This list of scopes a block can see is called the blocks environment. Consider the following examples: In the following example, the :py:func:`bar` function sees :py:func:`bar`'s scope and global scope, as shown with the highlighted lines. .. literalinclude:: scope_example0.py :linenos: :emphasize-lines: 2-6, 14-15 In the following example, the :py:func:`baz` functions sees :py:func:`baz`'s scope, :py:func:`bar`'s scope and global scope, as shown with the highlighted lines. .. literalinclude:: scope_example0.py :linenos: :emphasize-lines: 2-11 .. warning:: The search for variables is done during execution, not bytecode compile time. In the code below, even though ``val`` was defined prior to :py:func:`foo`, ``val`` is updated with a new value before ``foo`` is called. This will cause :py:func:`foo` to print the value 200, not 10. >>> val = 10 >>> def foo(): >>> print(val) >>> val = 200 >>> foo() 200 (Motivation for this example taken from the Python language reference [1]_) .. _section_heading-Tweaking_The_Rules: Tweaking The Rules ------------------ Python provides some built-in functions for altering how it finds variables (names). First, consider the following example as the base case. Each function has access to its own local variable ``x``. When each function is executed, it only modifies its local variable ``x``. .. literalinclude:: scope_example1.py :linenos: :emphasize-lines: 2,8,13 The above code produces the following output: .. code-block:: text mod level 'x': 1 bar level 'x': 2 baz level 'x': 3 bar level 'x': 2 mod level 'x': 1 We can use the :py:func:`nonlocal` function to tell Python that we want to refer to a variable in an enclosing *function* block. In the code below. the :py:func:`baz` function modifies ``x`` in an enclosing scope, in this case that of :py:func:`bar`. .. literalinclude:: scope_example2.py :linenos: :emphasize-lines: 13 The above code produces the following output: .. code-block:: text :emphasize-lines: 4 mod level 'x': 1 bar level 'x': 2 baz level 'x': 3 bar level 'x': 3 mod level 'x': 1 Finally, we can use the :py:func:`global` function to tell Python that we want to refer to a variable in the global scope. In the code below, the :py:func:`baz` function modifies ``x`` in the global scope: .. literalinclude:: scope_example3.py :linenos: :emphasize-lines: 13 The above code produces the following output: .. code-block:: text :emphasize-lines: 5 mod level 'x': 1 bar level 'x': 2 baz level 'x': 3 bar level 'x': 2 mod level 'x': 3 .. tip:: As a general rule, don't write code that changes variables that were defined outside the current scope. Doing so just makes it confusing to read, understand, test, debug and maintain that code. .. _section_heading-Searching_the_Global_Namespace: Search the Global Namespace --------------------------- Earlier, it was noted that Python searches the various scopes to find the nearest enclosing scope that contains a variable (name) that matches. As discussed, the outer most scope Python can search is the global scope. This is mostly correct. What wasn't mentioned until now is that if the name still isn't found by the time the search of the global scope completes, Python will search one more area, the builtins_ module. The builtins module contains all the `built-in functions`_ and `built-in constants`_ that are part of the Python interpreter and are always available. In addition to viewing documentation about the builtins online, you can view it from within the interpreter. The builtins module is a special module, so, it uses Python's naming scheme for special names (see :ref:`section_heading-Identifiers`) which uses dunder-dunder notation. Specifically, ``__builtins__``. Give it a try: >>> dir(__builtins__) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', ... 'tuple', 'type', 'vars', 'zip'] Also try: >>> help(__builtins__) .. _builtins: https://docs.python.org/3.5/library/builtins.html#module-builtins .. _built-in functions: https://docs.python.org/3.5/library/functions.html#built-in-funcs .. _built-in constants: https://docs.python.org/3.5/library/constants.html#built-in-consts .. [1] https://docs.python.org/3.5/reference/executionmodel.html#interaction-with-dynamic-features