On Jan 21, 11:24 am, Arnaud Delobelle <arno...@googlemail.com> wrote: > Falcolas <garri...@gmail.com> writes: > > I'm running into an issue with closures in metaclasses - that is, if I > > create a function with a closure in a metaclass, the closure appears > > to be lost when I access the final class. I end up getting the text > > 'param' instead of the actual tags I am expecting: > > > ALL_TAGS = ['a', 'abbr', 'acronym', 'address', 'applet', 'b', 'bdo', > > 'big'] #snip > > > def _tag_meta(name, bases, dict_): > > for tag in ALL_TAGS: > > def generic_tag(*args, **kwargs): > > return Tag._generate_tag(tag, *args, **kwargs) > > #generic_tag = eval("lambda *args, **kwargs: Tag._generate_tag > > ('%s', *args, **kwargs)" % tag) > > dict_[tag] = staticmethod(generic_tag) > > return type(name, bases, dict_) > > This is almost a FAQ and has nothing to do with metaclasses. The > simplest solution usually involves adding a default argument 'tag=tag' > to the function you define (here, generic_tag), but you can't do this > here because you have a **kwargs argument. Instead, you can use a > closure and do this for example: > > def factory(tag): > def generic_tag(*args, **kwargs): > return Tag._generate_tag(tag, *args, **kwargs) > return generic_tag > > def _tag_meta(name, bases, dict_): > for tag in ALL_TAGS: > dict_[tag] = staticmethod(factory(tag)) > return type(name, bases, dict_)
I see - I was thinking it would preserve the closure from the for statement, but I can see now why that would be wrong. > > However, I am usure about why you are using a metaclass. > > HTH > > -- > Arnaud It was the easiest way I found to add a lot of static methods to the Tag class without writing each one out. __getattr__ was not working for this application. This is for a very simple application, and I didn't want to add a lot of complexity to it's use. I'm always open for other options OTOH. -- http://mail.python.org/mailman/listinfo/python-list