Closures in metaclasses

Falcolas garrickp at gmail.com
Thu Jan 21 12:52:32 EST 2010


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_)

class Tag(object):
    __metaclass__ = _tag_meta
    @staticmethod
    def _generate_tag(tag_name, *args, **kwargs):
        # Does the expected, following is just for the example's sake
        return tag_name

Here's the output from my actual class:
$ python
Python 2.6.4 (r264:75706, Dec  7 2009, 18:45:15)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from htmlgen import Tag
>>> Tag.html("foo")
'<param>\nfoo\n</param>'
>>>

Using the eval shown above works as expected, but I'd rather go with
the closures, if someone can help me figure out what's going on.



More information about the Python-list mailing list