The setter() you set the local variable x . Assigning a name to a function designates it as local unless you specifically specify the Python compiler otherwise.
In Python 3, you can explicitly mark x as non-local using the nonlocal keyword:
def make_adder_and_setter(x): def setter(n): nonlocal x x = n return (lambda y: x + y, setter)
Now x is marked as a free variable and is viewed in the environment, not at the destination.
In Python 2, you cannot mark local Python as such. The only other option you have is to mark x as global . You have to resort to tricks in which you change the values contained in a mutable object that lives in the environment.
The setter function attribute will work, for example; setter is local to make_adder_and_setter() , the attributes of this object will be visible to everyone with access to setter :
def make_adder_and_setter(x): def setter(n): setter.x = n setter.x = x return (lambda y: setter.x + y, setter)
Another trick is to use a mutable container, like a list:
def make_adder_and_setter(x): x = [x] def setter(n): x[0] = n return (lambda y: x[0] + y, setter)
In both cases, you no longer assign a local name; the first example uses attribute assignment for the setter object, the second modifies the list x , and is not assigned to x itself.
source share