On Tue, 6 Jul 2004, C GIllespie wrote:
What is a quick way of generating all these methods? I'm thinking along the
lines of:
class file:
formats=['ps', 'ps2', 'hpgl', 'pcl', 'mif', 'pic', 'gd', 'gd2', 'gif',
'jpg']
def __init__(self):
for frmt in self.formats:
self.__setattr__('file2'+frmt, ???)
I've tried a variety of things where ??? is, but with no success.
You've probably tried using ??? = lambda: frmt, with the effect that all
the functions return 'jpg'. This has bit me before, too. The problem with
this approach is that frmt is not evaluated inside the lambda -- after the
loop has finished, you end up with a bunch of "lambda: frmt"s, and frmt is
left equal to "jpg". The way to fix this is to force frmt to be evaluated,
as follows:
class file:
formats=['ps', 'ps2', 'hpgl', 'pcl', 'mif', 'pic', 'gd', 'gd2', 'gif',
'jpg']
def __init__(self):
for frmt in self.formats:
setattr(self, 'file2'+frmt, self.genfunc(frmt))
def genfunc(self,frmt):
return lambda: frmt
Calling genfunc() forces frmt to be evaluated before being re-bound and
passed to the lambda.
There are a couple of problems with placing this all in __init__, however:
the functions are generated each time you create a new file object, and
they aren't passed a "self" reference. To fix these problems, it's best to
add all the methods to the class itself, and not the individual objects:
class file:
formats=['ps', 'ps2', 'hpgl', 'pcl', 'mif', 'pic', 'gd', 'gd2', 'gif',
'jpg']
def genfunc(frmt):
return lambda self: frmt
genfunc=staticmethod(genfunc)
for frmt in file.formats:
setattr(file, 'file2'+frmt, file.genfunc(frmt))
Note that neither formats nor genfunc() need to be members of file; if it
suits your taste better, the same thing can be written as:
class file:
pass
formats=['ps', 'ps2', 'hpgl', 'pcl', 'mif', 'pic', 'gd', 'gd2', 'gif',
'jpg']
def genfunc(frmt):
return lambda self: frmt
for frmt in formats:
setattr(file, 'file2'+frmt, genfunc(frmt))
Personally, I prefer the version using static attributes of the class, but
either way will work as well.