Programmer's Python - Local and Global
Written by Mike James   
Monday, 28 January 2019
Article Index
Programmer's Python - Local and Global
Inner Functions

Inner Functions

You can define a function anywhere in code. When you first start with Python this generally means defining functions within a module i.e. at the “top level”. However, there is nothing wrong with defining functions within the code of another function.

For example:

def myFunction():
    def myInnerFunction():
        myInnerVariable=20
        print(myInnerVariable)
    
    myInnerFunction()    
myFunction()

Notice that myFunction contains a definition of another function, myInnerFunction. This has a single local variable, myInnerVariable, which it prints. Calling the outer function, myFunction results in calling the inner function and the display of its local variable.

You can repeat this as many times as you like defining one function in the code of another. In practice it is rare for functions to be nested more than one deep but there is nothing in Python that rules it out. Each function is local to the function that immediately contains its definition.

Local, Global and Nonlocal

This should be all very clear and obvious but notice that in the preceding example we have created two function objects. The first comes into existence immediately i.e. the one referenced by myFunction. The second only comes into existence when we call myFunction and its code is executed i.e. the one referenced by myInnerFunction.

Notice that the local variables for the inner function only exist while it is being executed and so there is no prospect of the outer function accessing them. However, the local variables of the outer function exist for the entire time that the inner function is executing – can it access them? In other words, are the containing function’s local variables like globals to the inner function?

The answer is yes, but it is far more involved a story than you might imagine.

The reason is once again the fact that Python has no keyword for defining a variable. When you assign to a variable it is created if it doesn’t already exist in the local context.

What this means is that the inner function can access the local variables of the outer function, but it cannot assign to them without taking an extra step.

For example:

def myFunction():
    myOuterVariable=10
    def myInnerFunction():
        print(myOuterVariable)
    myInnerFunction()    
myFunction()

This accesses myOuterVariable as defined as a local variable of myFunction. However, if you assign to myOuterVariable within the inner function a local variable is created:

def myFunction():
    myOuterVariable=10
    def myInnerFunction():
        myOuterVariable=20
        print(myOuterVariable)
    myInnerFunction()
    print(myOuterVariable)
myFunction()

This prints 20 followed by 10 demonstrating that the inner function used its own local variable and didn’t use the outer variable.

If you want to assign to an outer variable you have to declare it as nonlocal. The nonlocal statement works like the global statement in that it stops assignment from creating a local variable.

For example:

def myFunction():
    myOuterVariable=10
    def myInnerFunction():
        nonlocal myOuterVariable
        myOuterVariable=20
        print(myOuterVariable)
    myInnerFunction()
    print(myOuterVariable)
myFunction()

declaring myOuterVariable nonlocal stops the Python system from creating a new local variable and forces it to search for the variable in the variable table of the enclosing function. That is, what you see printed is 20 followed by 20 as the variable defined in the outer function is used.

You might ask what is the difference between nonlocal and global.

Declaring a variable as global within a function will either create the global variable or make use of the one already defined. Notice this has to be a global variable defined at the module level.

Declaring a variable as nonlocal within a function makes use of the variable defined within the containing function. If there isn’t one then the next containing function is used to supply the variable and so on. If no variable that is local to a containing function is found then an error occurs.

This means that a nonlocal declaration never creates a new variable and never makes use of a global variable. It searches any set of nested functions from the innermost and uses the first variable of the same name it finds.

This might seem complicated but it is a perfectly logical consequence of Python defining a variable by assignment.

  • Use global in a function when you want to use or create a global variable.

  • Use nonlocal in a function when you want to use the first local variable available in the containing functions.

 

Closure

See book for final version

A Common Error

See book for final version

What Use is Closure?

 See book for final version

Private State Variables

See book for final version

Function Self Reference

See book for final version

Callbacks

See book for final version

Closures __closure__ and Cells (Advanced)

See book for final version

Summary

 

  • A variable that a function assigns to is created as a local variable.

  • To reference a global variable that the function assigns to it has to be declared as global.

  • Functions can be defined within other functions and the inner functions have access to the containing function’s local variables but not vice versa.

  • If an inner function assigns to a variable then it is created as a local variable.

  • To refer to a local variable of a containing function in assignment you have to declare the variable nonlocal.

  • Closure is a natural consequence of function objects outliving their local variables. If an inner function exists and can be invoked after its containing function has ended, then it still has access to the same local variable via the closure.

  • The closure consists of all of the variables in scope when a function is declared – its execution context.

  • All functions declared within the same execution context share that context as their closure.

  • The values of variables in the closure are the last values they had before the outer function terminated.

  • Closures have many uses but the main ones are to provide private state variables, provide a self reference, and to provide context to callback functions.

  • You can work with the __closure__ magic attribute to access and even change the closure but how this works is platform dependent. Use the inspect module to isolate your code from such changes.

Programmer's Python
Everything is an Object

Is now available as a print book: Amazon

pythoncover


Contents

  1. Hello Python World
  2. Variables, Objects and Attributes
  3. The Function Object
      Extract - Function Objects
  4. Scope, Lifetime and Closure
      Extract - Local and Global
      Extract - Closure ***NEW
  5. Advanced Functions
      Extract - Parameters
      Extract - Decorators 
  6. Class Methods and Constructors
      Extract -  Objects Become Classes
  7. Inside Class
  8. Metaclass
  9. Advanced Attributes
      Extract - Properties
  10. Custom Attribute Access
      Extract -  Custom Attributes
      Extract -  Default Methods
  11. Single Inheritance
  12. Multiple Inheritance
  13. Class and Type
      Extract - Class & Type
  14. Type Annotation
      Extract - Type Annotation 
  15. More Magic - Operator Overloading

 

Advanced Attributes

Related Articles

Creating The Python UI With Tkinter

Creating The Python UI With Tkinter - The Canvas Widget

The Python Dictionary

Arrays in Python

Advanced Python Arrays - Introducing NumPy

square

 



 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner

<ASIN:1871962587>

 

 



Last Updated ( Monday, 21 October 2019 )