On Wed, Apr 22, 2009 at 4:50 AM, Rüdiger Ranft <_r...@web.de> wrote: > Hi all, > > I want to generate some methods in a class using setattr and lambda. > Within each generated function a name parameter to the function is > replaced by a string constant, to keep trail which function was called. > The problem I have is, that the substituted name parameter is not > replaced by the correct name of the function, but by the last name the > for loop has seen. > > import unittest > > class WidgetDummy: > '''This class records all calls to methods to an outer list''' > > def __init__( self, name, calls ): > '''name is the name of the object, which gets included into a > call record. calls is the list where the calls are appended.''' > self.name = name > self.calls = calls > for fn in ( 'Clear', 'Append', 'foobar' ): > func = lambda *y,**z: self.__callFn__( fn, y, z ) > setattr( self, fn, func )
Common wart to run into as of late. fn (in the lambda) doesn't get evaluated until the call-time of the lambda, by which point the loop has finished and the loop variable has been changed to its final value, which is used by the lambda. Workaround: #exact syntax may vary with your version of Python, but you should be able to get the idea func = lambda *y,**z, fn=fn: self.__callFn__( fn, y, z ) The default argument value gets evaluated at definition-time, thus forcing the right value of fn within the function. Cheers, Chris -- I have a blog: http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list