Hacker News new | past | comments | ask | show | jobs | submit login

   >>> def makeAdder(x):
   	def inc(y):
   		return y+x
   	return inc
   
   >>> f = makeAdder(3)
   >>> f(4)
   7
So far, so good.

   >>> def makeAdder2(x):
   	v = x
   	def inc(y):
   		v += y
   		return v
   	return inc
   
   >>> f2 = makeAdder2(3)
   >>> f2(4)
   
   Traceback (most recent call last):
     File "<pyshell#15>", line 1, in <module>
       f2(4)
     File "<pyshell#13>", line 4, in inc
       v += y
   UnboundLocalError: local variable 'v' referenced before assignment
   >>>
It looks like you can't mutate variables in a closure. Am I doing it wrong? If you really can't, that seriously limits their power.

--

In Lua:

  > function adder(x)
      local v = x
      function inc(y)
          v = v + y
          return v
          end
      return inc
      end
  >> >> >> >> >> >> >> > f = adder(3)
  > =f(4)
  7
  > =f(4)
  11
  > =f(4)
  15
  >
Works fine. (Also, the syntax is really clean.)



Python 3.0 fixes this with the nonlocal statement. However, you are correct that this doesn't work in Python 2.5 and earlier.


Ok, thanks.


Argh - I can't get the formatting to work.

def makeAdder2(x):

    v = [x,]
    def inc(y):
        v[0] += y
   	return v[0]
    return inc
works just fine in all pythons with closures (2.0 and above?)

def makeAdder2(x):

    def inc(y, v=[x,]):
        v[0] += y
   	return v[0]
    return inc
Also works and provides a mechanism for resetting the state.


Interesting. So keeping a reference to a list with the value works, but the value directly doesn't? Thanks for the note.

Good to know it's possible, though I'd rather it handle closures / lexical scoping directly.


You may need to add a 'global' statement or something similiar. If you are going to mutate a variable in a function Python assumes that you want to create a new variable in that scope.

Generally I do not mutate variables as far as possible, so I have not hit this problem myself, yet. Perhaps there is someone more knowledgeable about Python to step in.


But it's not a global variable, it's scoped within the closure. So, this means Python doesn't have lexical scoping?


It has. Just the syntax was a bit awkward when modifying variables of higher scope. See sibling comment.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: