yarbelk yarbelk - 1 year ago 61
Python Question

Python metaclass arguments

I'm trying to dynamically generate classes in python 2.7, and am wondering if you can easily pass arguments to the metaclass from the class object.

I've read this post, which is awesome, but doesn't quite answer the question. at the moment I am doing:

def class_factory(args, to, meta_class):
Class MyMetaClass(type):
def __new__(cls, class_name, parents, attrs):
attrs['args'] = args
attrs['to'] = to
attrs['eggs'] = meta_class

class MyClass(object):
metaclass = MyMetaClass

but this requires me to do the following

MyClassClass = class_factory('spam', 'and', 'eggs')
my_instance = MyClassClass()

Is there a cleaner way of doing this?

Answer Source

Yes, there's an easy way to do it. In the metaclass's __new__() method just check in the class dictionary passed as the last argument. Anything defined in the class statement will be there. For example:

class MyMetaClass(type):
    def __new__(cls, class_name, parents, attrs):
        if 'meta_args' in attrs:
            meta_args = attrs['meta_args']
            attrs['args'] = meta_args[0]
            attrs['to'] = meta_args[1]
            attrs['eggs'] = meta_args[2]
            del attrs['meta_args'] # clean up
        return type.__new__(cls, class_name, parents, attrs)

class MyClass(object):
    __metaclass__ = MyMetaClass
    meta_args = ['spam', 'and', 'eggs']

myobject = MyClass()

from pprint import pprint
print myobject.args, myobject.to, myobject.eggs


spam and eggs