user6461080
user6461080

Reputation: 140

Given a multi-nested Python function, how can I access a closure variable all the way down in some arbitrarily nested function?

I understand that in most cases nonlocal and global keywords allow inner functions to have access to either the outer function's variables or overall global variables. But the typical closure examples I've seen usually only nest to 2 levels (e.g. 1 outer and 1 inner function). I'm curious how we can access a variable in the first function scope all the way deep in some nested function scope. I know this type of programming doesn't appear often but I'm curious what the answer is

Please see example below

def pseudo_global():     # layer 1 -- first outer function  
    a = "global"
    def block():         # layer 2 
        def show_a():    # layer 3 
            nonlocal a   # doesn't do anything here because "a" isn't defined in block() scope 
#            global a    # commented out; nothing prints anyway because refers to global scope 
            print(a)     # free variable error; how can I access layer 1's variable here in layer 3? 

        show_a()
        a = "block"
        show_a()
    block()

pseudo_global()

Upvotes: 1

Views: 823

Answers (1)

Frank Yellin
Frank Yellin

Reputation: 11297

nonlocal a is precisely what you need. The issue is that you need two of them. You need to tell both block() and show_a() that a is nonlocal.

The definition of nonlocal is to cause the variable to refer to the previously bound variable in the nearest enclosing scope, excluding globals.

def pseudo_global():     # layer 1 -- first outer function  
    a = "global"
    def block():         # layer 2 
        nonlocal a
        def show_a():    # layer 3 
            nonlocal a   
            print(a)     
        a = "block"
        show_a()
    block()

pseudo_global()
global
block

Upvotes: 3

Related Questions