Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Python's closure works

Tags:

I am trying to understand how closure works in Python, and I've found the following code snippet:

def closure():
    count = 0
    def inner():
        nonlocal count
        count += 1
        print(count)
    return inner

start = closure()
start() # prints 1
start() # prints 2
start() # prints 3

I can understand this code, as when inner function is defined, the enclosing scope has a variable named count with value 0, and the inner function will remember this value then

However, if I then move count = 0 below inner function, so the code becomes like:

def closure():
    def inner():
        nonlocal count
        count += 1
        print(count)
    count = 0
    return inner

start = closure()
start() # prints 1
start() # prints 2
start() # prints 3

To my surprise, the code still works perfectly fine, which really confuses me. As when inner is defined, the variable count doesn't exist in the enclosing scope, how could inner function is able to remember a value that doesn't exist in the namespace at this point yet?

Is it because something similar to JS's variable hoisting also exist in Python?

like image 861
torez233 Avatar asked Sep 04 '19 05:09

torez233


1 Answers

In both of the examples, you are receiving the value returned by the closure method in start variable i.e. the method closure gets executed and returns the inner local method. So the count variable is also get defined and initialized with value 0

When you invoke inner method by using start(), that method gets executed and by that time, in both cases, the count variable is already there

But if you have code something like this, then there will be a reference error

def closure():
    def inner():
        nonlocal count
        count += 1
        print(count)
    inner()
    count = 0

start = closure()

Here inner method is called before count is defined

like image 75
Sajeer Noohukannu Avatar answered Nov 25 '22 21:11

Sajeer Noohukannu