1

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()
3
  • 1
    You can put nonlocal a inside block() function. It prints global, block. Commented Oct 28, 2020 at 23:21
  • You don't actually need nonlocal in show_a(). It's only needed in functions that assign to the variable. References automatically search enclosing scopes. Commented Oct 28, 2020 at 23:29
  • thank you -- is there a way to have it print "global global"? I see that because we declared "a" as nonlocal in block()'s scope, when we re-assign a = "block" the show_a() function will call this new "a" but is the old a = "global" still there in our pseudo-global() scope? Commented Oct 28, 2020 at 23:29

1 Answer 1

3

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
Sign up to request clarification or add additional context in comments.

1 Comment

You don't even need it in show_a() since it doesn't assign the variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.