Welcome, guest | Sign In | My Account | Store | Cart

Alternative notation for defining closures in python; It avoids packing closure variables into containers by assigning attributes to the inner function.

Python, 28 lines
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28``` ```# nice and clean closure notation def get_counter_neat(): def f(): f.x += 1 return f.x f.x = 0 return f # traditional, not_so_neat closure notation def get_counter_traditional(): x = [0] def f(): x[0] += 1 return x[0] return f #### EXAMPLE ########################################################### cnt_a = get_counter_neat() cnt_b = get_counter_neat() print cnt_a() # >>> 1 print cnt_a() # >>> 2 print cnt_a() # >>> 3 print cnt_b() # >>> 1 print cnt_a() # >>> 4 print cnt_b() # >>> 2 print cnt_b() # >>> 3 ```

Matt Good 18 years, 1 month ago

Updating closure variables. I think it's worth noting that this also makes it easy to update the closure variables since they're attributes of the function:

``````>>> cnt_a = get_counter_neat()
>>> cnt_a()
1
>>> cnt_a()
2
>>> cnt_a.x = 10
>>> cnt_a()
11
``````
bearophile - 18 years, 1 month ago

Possible fix. Probably this is what you want:

cnt_a = get_counter_neat()

bluecamel 13 years, 12 months ago

I'm curious why you wouldn't just use a class:

``````class counter:
def __init__(self):
self.x = 0

def __call__(self):
self.x += 1
return self.x

cnt_a = counter() # works exactly like all of the other examples, and you have access to cnt_a.x, etc...
``````

It's also just as easy to specify starting and increment values:

``````class counter:
def __init__(self, start = 0, inc = 1):
self.x = start - inc
self.inc = inc

def __call__(self):
self.x += self.inc
return self.x

a = counter(10, 10) # create a counter starting at 10, incrementing by 10 each time
print a() # prints 10
print a() # prints 20
``````
 Created by Maciej Obarski on Tue, 7 Mar 2006 (PSF)

### Required Modules

• (none specified)