Variable Global and Local Scope in a Nested Function

Example 1- Calling an Inner function  
Input
x = 500
def check_func(): ---Local Scope 
    x = 250
    def check_again_func():
        x = 550
        print(x)
    check_again_func() 

Output 
550 

Example 1.2  ---Enclosing Scope 
Input
x = 500
def check_func():
    x = 250
    def check_again_func():
        print(x)
    check_again_func()

Output 
250




Example #2.1 Inner and Outer function have a variable
x=500
def check_func():
    x=777
    def check_again_func():
        x=550
        print(x)
    check_again_func()
    print(x)
Output 
550
777

Example 2.2  Only Inner function has a variable
Input 
x=500
def check_func():
    def check_again_func():
        x=550
        print(x)
    check_again_func()
    print(x)
Output 
550
500

Example #2.3  Inner Function has a global variable but outer function has a local variable, Local scope overrules Global variable in a function call
Input
x=500
def check_func():
    x=777
    def check_again_func():
        global x
        x=550
        print(x)
    check_again_func()
    print(x)

Output 
550
777

Example 2.4   Outer function has no local variable and inner function updates the global variable. 
Input
x=500
def check_func():
    def check_again_func():
        global x
        x=550
        print(x)
    check_again_func()
    print(x)
Output
550

In the example 1, I am calling the inner function check_again_func() and that basically returns output based on Local scope in 1 and Enclosing Scope in 1.2.

In the example 2, I wanted to check how the outer function reacts to LEGB rule, based on all the example from 2 and onwards, I concluded:

  1. Inner function local variable is not local to the outer function
  2. Inner function enclosing variable does not apply to the outer function
  3. Inner function global keyword apply to the outer function only when the local variable is not present in the outer function to overrule it.

Am I understanding this correct? Please let me know

All statements are true. It helps to print the variable x after the function call to verify its final value. See script below - slightly edited.

Just one small suggestion, I would advise to space out your script a little bit so that it enhances its legibility - but maybe that’s just me.


x = 500
print(f'\nStarting value of global {x}\n')

def check_func():

    x = 777

    def check_again_func():

        global x   # x is now visible globally

        x = 240    # changes value of global x

        print(x)

    check_again_func()

    print(x)

check_func()

print('\nFinal value of global x: ', x)

Cheers!

1 Like

There is immutability and mutability in Python. So code below can be written:

def outer():
    spam = [1]
    def inner():
        spam[0] = 2
        print(spam)
    inner()
    print(spam)

outer()

# [2]
# [2]

eggs = [1]
print(eggs)
print(eggs[0])

#[1]
# 1

def outer():
    eggs[0] = 2

outer()
print(eggs)
print(eggs[0])

# [2]
# 2


1 Like

Appreciate your response. Yes, I will keep that in mind

spam=[2,3]
def outer():
    spam = [1,2]
    def inner():
        spam=[6,7]
        print(spam)
    inner()
    print(spam)
Output
[6,7]
[1,2]

That makes sense because it is still the same variable in your case. Only the element inside was updated. I was confused about the cases where there are two variables with the same name, one in the outer function and one in the inner function and what happens if we call the outer function

It is probably worth to take a look at Python glossary: closure variable, nested scope and associated documentation.

1 Like