Closures / Blocks in Python

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Thu Jul 26 02:04:04 CEST 2007


En Wed, 25 Jul 2007 11:45:00 -0300, Jeff <jeffober at gmail.com> escribió:

> You can create a lexical closure using a Python generator function,
> which allows iteration using a block of code while maintaining
> internal state.  A generator is a regular function which uses yield
> (like Ruby) to define the point at which the function should return an
> expression to the calling code.  For example:
>
> # Generic counter
> def counter(min=None, max):
>   if not min:
>     min = 0
>   for i in xrange(min, max):
>     yield i
>     i = i + 1
>
> When called, this function will yield the value of i and remember its
> state.  The next time it's called, it will increment i, then continue
> on another iteration of the loop, yielding the new value of i.
>
> For example:
>
> my_counter = counter(0, 10)
> my_counter() # <-- 0
> my_counter() # <-- 1
> for i in my_counter():
>   print i
> # Prints 2-10 (the remaining numbers in xrange(min, max))

Uhmm, I think this won't win the Best Python Code Of The Week Award :)
Apart from the already noted syntax error in the function definition, the  
`i = i + 1` is useless because `i` gets reassigned right on the next loop.
And you don't "call" a generator, you have to iterate over it;  
my_counter() will raise an error. This would be the right way:

my_counter = counter(0, 10)
my_counter.next() <-- 0
my_counter.next() <-- 1
for value in my_counter:
   print value  <-- 2 to 9

-- 
Gabriel Genellina




More information about the Python-list mailing list