Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python closure with side-effects

I'm wondering if it's possible for a closure in Python to manipulate variables in its namespace. You might call this side-effects because the state is being changed outside the closure itself. I'd like to do something like this

def closureMaker():
  x = 0
  def closure():
    x+=1
    print x
  return closure

a = closureMaker()
a()
1
a()
2

Obviously what I hope to do is more complicated, but this example illustrates what I'm talking about.

like image 981
Mike Avatar asked Jul 03 '11 23:07

Mike


2 Answers

You can't do exactly that in Python 2.x, but you can use a trick to get the same effect: use a mutable object such as a list.

def closureMaker():
    x = [0]
    def closure():
        x[0] += 1
        print x[0]
    return closure

You can also make x an object with a named attribute, or a dictionary. This can be more readable than a list, especially if you have more than one such variable to modify.

In Python 3.x, you just need to add nonlocal x to your inner function. This causes assignments to x to go to the outer scope.

like image 119
interjay Avatar answered Oct 22 '22 04:10

interjay


What limitations have closures in Python compared to language X closures?

nonlocal keyword in Python 2.x

Example:

def closureMaker():
     x = 0
     def closure():
         nonlocal x
         x += 1
         print(x)
     return closure
like image 45
ninjagecko Avatar answered Oct 22 '22 04:10

ninjagecko