Learn

Similar to how nested functions form a unique namespace within their enclosing functions (the enclosing namespace), there also exist special rules that apply for accessing nested values. These rules make up the enclosing scope (also known as nonlocal scope). Let’s take a look at a nested function to see the scope in action:

def outer_function(): enclosing_value = 'Enclosing Value' def nested_function(): nested_value = 'Nested Value' print(enclosing_value) nested_function() outer_function()

Our output would be:

Enclosing Value

Enclosing scope allows any value defined in an enclosing function to be accessed in nested functions below it. We can observe this scope since nested_function() can access a variable defined one level above in the enclosing function (outer_function()).

We can also observe this scoping rule further if we nested a function one level deeper:

def outer_function(): enclosing_value = 'Enclosing Value' def nested_function(): nested_value = 'Nested Value' def second_nested(): print(enclosing_value) print(nested_value) second_nested() nested_function() outer_function()

Would output:

Enclosing Value Nested Value

There are two caveats to be aware of with enclosing scope:

  • The flow of scope access only flows upwards. This means that the deepest level has access to every enclosing namespace above it, but not the other way around. For example, if we tried to access nested_value from one level above where it was defined:

    def outer_function(): enclosing_value = 'Enclosing Value' print(nested_value) def nested_function(): nested_value = 'Nested Value' nested_function() outer_function()

    The program would produce an error:

    NameError: name 'nested_value' is not defined
  • Immutable objects, such as strings or numbers, can be accessed in nested functions, but cannot be modified. Let’s try to change enclosing_value to see this restriction in action:

    def outer_function(): enclosing_value = 'Enclosing Value' def nested_function(): enclosing_value += 'changed' nested_function() print(enclosing_value) outer_function()

    Would output:

    UnboundLocalError: local variable 'enclosing_value' referenced before assignment

Let’s now practice accessing values in the enclosing scope!

Instructions

1.

A new addition to our painting application that we are building for Jiho will be a function that calculates the amount of paint needed to cover a surface.

Typically, a gallon of paint can cover about 400 square feet. Using that knowledge, we can use the width and height of a surface to determine how much paint is needed!

Throughout these exercises we will use nested functions to add more utility to the calc_paint_amount() function. Remember, this now makes calc_paint_amount() an enclosing function.

Run the code to move to the next exercise.

2.

First inside of calc_paint_amount():

  • Define a nested function called calc_gallons() that has no parameters.

Then inside of calc_gallons(), use enclosing scope to access the variable square_feet from the calc_gallons() function.

  • Return the result of square_feet divided by 400.
3.

Finally, in the calc_paint_amount() function, call the calc_gallons() function and return the result. Run the code and take a look at the result!

Sign up to start coding

By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.
Already have an account?