I’m used to the JavaScript mindset, where I have closure in basically.. everywhere.

However, the local-variable is handled pretty ugly in Python:

def f:
  cnt = 0;
  
  def localFunction:
    console.log(cnt)
    cnt += 1
  end
end

The code above would raise error UnboundLocalError: local variable 'cnt' referenced before assignment

However, if you use it like below:

def f:
  cnt = 0;
  
  def localFunction:
    console.log(cnt)
  end
end

i.e., no assignment involved, it would then be fine.

This is because that, whenever there’s an assignment, python would believe that there’s a new variable in the current scope, and try to initialize memory before coming into the scope; this part of memory would hide variables with the same name in its parent scope. Thus, before the actual assignment, it’s considered as “undefined”.

If one needs such implementation, and don’t want to use class, one can do some ugly trick by using a single element array to bypass the problem:

def f:
  cnt = [0];
  
  def localFunction:
    console.log(cnt[0])
    cnt[0] = cnt[0] + 1
  end
end

In Javascript, similiar problem happends, but it’s less nasty. Thanks to the infamous var declaration (which python don’t have). In the code below:

  
(function(){
  var cnt = 0

  var f = function(){
    console.log("cnt = " + cnt++);
    var cnt = 1;
  }

  for(var i = 0 ; i < 2 ;i++){
    f();
  }
})()
  

It would output:

cnt = NaN
cnt = NaN

instead. Since there is a var cnt = 1, the variable would be allocated with memory when entering the scope (although not yet initialized).

This is better than python, because whenever such case happens, almost always it’s because the code itself is ugly. One can simply bypass the problem by renaminmg it.