Closure in python?
closures, python, python-2.x
Solution
Python 2.x has a syntax limitation that doesn't allow to capture a variable in read/write.
The reason is that if a variable is assigned in a function there are only two possibilities:
- the variable is a global and has been declared so with `global x`
- the variable is a local of the function
more specifically it's ruled out that the variable is a local of an enclosing function scope
This has been superseded in Python 3.x with the addition of `nonlocal` declaration. Your code would work as expected in Python 3 by changing it to
def make_adder_and_setter(x):
def setter(n):
nonlocal x
x = n
return (lambda y: x + y, setter)
The python 2.x runtime is able to handle read-write closed over variable at a bytecode level, however the limitation is in the syntax that the compiler accepts.
You can see a lisp compiler that generates python bytecode directly that creates an adder closure with read-write captured state at the end of this video. The compiler can generate bytecode for Python 2.x, Python 3.x or PyPy.
If you need closed-over mutable state in Python 2.x a trick is to use a list:
def make_adder_and_setter(x):
x = [x]
def setter(n):
x[0] = n
return (lambda y: x[0] + y, setter)
Problem
When I run this code, I get this result: ``` 15 15 ``` I expect the output should be ``` 15 17 ``` but it is not. The question is: why? ``` def make_adder_and_setter(x): def setter(n): x = n return (lambda y: x + y, setter) myadder, mysetter = make_adder_and_setter(5) print myadder(10) mysetter(7) print myadder(10) ```