SoFunction
Updated on 2024-11-16

Comparison of closures in Python, Javascript

As scripting languages, python and Javascript have similar variable scopes, unlike php, where all variables inside a function are isolated from the outside, i.e., in order for a function to process data outside of it, it must pass in the data to be processed using parameters (the use of the global keyword will not be discussed here). Unlike Javascript, if a variable is declared in a function, it will be looked up in a hierarchy until it returns a value or is undefined.

So in that case, closures in python should be simple, and like javascript, we write similar code:

def func1():
    a = 1
    def func2():
        a = a + 1
        return a
    return func2
re=func1()
print re()
print re()


However, in reality, instead of printing 2 and 3 as we expected, the result is this error: "UnboundLocalError: local variable 'a' referenced before assignment " (local variable 'a' referenced before assignment). Why this problem occurs, let's first look at js if the implementation of this closure:

<script>
 function func1(){
 var a=1;
  function func2(){
  a=a+1;
  return a;
  }
 return func2;
 }
re=func1();
(re());
(re());
</script>

The above code runs as expected, with inputs 2 and 3. Notice on line 5 of the program, if I put a var in front of it, what does the program look like? The end result is two "NaN" inputs, and the description of var is found in the Firefox developer platform:

Declares a variable, optionally initializing it to a value.
The scope of a variable declared with var is the enclosing function or, for variables declared outside a function, the global scope (which is bound to the global object).

It means that var is used to declare local variables. In the above example, if you use var a=a+1,then a is already a local variable in func2 and will not be inherited from func1, so you will end up with a NaN result.

Let's go back to this closure in python. this error message also means that a is a local variable. in fact, python specifies that all variables to the left of the assignment statement are local variables. this a is to the left of the equals sign, so it becomes a local variable, causing me to not be able to access a in func1. how can I solve this problem? If you are in python 3.0 or above, you can use nonloacal a to specify that a is not a local variable before a=a+1. Versions below 3.0 don't support the nonloacal keyword, so we can do this:

def func1():
    a = [1]
    def func2():
        a[0] = a[0] + 1
        return a[0]
    return func2
re=func1()
print re()
print re()

The result of the run printed 2 and 3 as we expected. from the example of python and Javascript closures, to understand the similarities and differences between python and js variable declarations, variable scopes.