F
Falcolas
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.
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.
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.
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.