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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With