Lambda forms and scoping

Benjamin Peterson benjamin at python.org
Thu Mar 19 23:31:32 CET 2009


Márcio Faustino <m.faustino <at> gmail.com> writes:

> 
> Hi,
> 
> Executing the example below doesn't produce the expected behavior, but
> using the commented code does. Is this normal, or is it a problem with
> Python? I've tested it with version 2.6.1 on Windows XP.
> 
> Thanks,
> 
> --
> 
> from abc import *
> from types import *
> import re
> 
> class Base (ObjectType):
>     __metaclass__ = ABCMeta
> 
>     def __init__(self):
>         for option in self.get_options().keys():
>             method = 'get_%s_option' % re.sub(' ', '_', option.lower
> ())
>             setattr(self.__class__, method, lambda self:
> self.get_option(option))

This is because the closure over option is changed when it is reassigned in the
for loop. For example:

>>> def f():
...     return [lambda: num for num in xrange(2)] 
... 
>>> f()
[<function <lambda> at 0x83f30>, <function <lambda> at 0x83e70>]
>>> f()[0]
<function <lambda> at 0x83ef0>
>>> g = f()
>>> g[0]()
1
>>> g[1]()
1







More information about the Python-list mailing list