1

Why does the following work:

def rec(a, b, c):
    global nmb_calls
    nmb_calls += 1
    # other stuff
    rec(...)

p_list = []
nmb_calls = 0 
rec(a=p_list, b, c)
print(p_list)

but something like:

def rec(a, b, c):
    nonlocal nmb_calls
    nmb_calls += 1
    # other stuff
    rec(...)

def call_rec(usr_b):
    p_list = []
    nmb_calls = 0
    rec(a=p_list, b=usr_b, c)
    return p_list

fail with the error: SyntaxError: no binding for nonlocal 'nmb_calls' found

I thought nonlocal means that rec would look up in the enclosing scope (that of call_rec), find nmb_calls and use that?

2
  • In the first situation, the nmb_calls is a global variable but not in the second one. Commented May 7, 2017 at 2:05
  • call_rec is NOT an enclosing scope of rec. You have to actually nest a function inside another to achieve that. Commented May 7, 2017 at 2:19

1 Answer 1

2

The reason the second case doesn't work is the way you're calling it in call_rec is not an enclosing scope that works with nonlocal. You'd have to do something like the following to call rec() using nonlocal for nmb_calls:

def enclosing_function():
    def rec(a, b, c):
        nonlocal nmb_calls
        nmb_calls += 1
        # other stuff
        #rec(...)

    p_list = []
    nmb_calls = 0
    rec(a=p_list, b=usr_b, c=None)
    return p_list

Also, just a heads up that you can't call rec without specifying the c parameter in the same way as you did for a and b.

So this doesn't work:

rec(a=p_list, b=usr_b, c)

but you can do the reverse:

rec(a, b, c=None)
Sign up to request clarification or add additional context in comments.

1 Comment

so the function has to be defined in the environment in order for non local scope to work? it is not enough to assume that the function will look up from the function where it is called?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.