python dynamically create class with inner class

class, metaclass, metaprogramming, python, tastypie

Solution

class MyModel(object) : pass
modelClass = MyModel()

class ModelResource(object):
    def mymethod(self):
        print('got here')

Meta = type('Meta', (object, ), {'allowed_methods': ['get']})

def add_mymethod(cls):
    def mymethod(self):
        super(cls, self).mymethod()
    cls.mymethod = mymethod
    return cls

name = modelClass.__class__.__name__ + "Resource"
MyModelResource = add_mymethod(type(name, (ModelResource, ),
                                    {'Meta':Meta, }))

print(MyModelResource.Meta)
# <class '__main__.Meta'>

m = MyModelResource()
m.mymethod()
# got here

The inner class, `Meta`, is just another attribute as far as `MyModelResource` is concerned.

Methods are also just attributes as far as `MyModelResource` is concerned. Actually, you define a function in `MyModelResource.__dict__`, and the Python attribute lookup mechanism causes `inst.mymethod` to return a bound method.

There is no problem referring to `MyModelResource` in the `super` call

super(MyModelResource, self).mymethod()

before `MyModelResource` is defined, because name lookups are performed at run time, not at the time `mymethod` is defined.

You are absolutely correct that

super(self.__class_, self).mymethod()

is wrong. This will spoil all that is good about `super`. If `MyModelResource` were to be subclassed, and an instance of the subclass were to call `mymethod`, then Python would fall into an infinite loop.

Problem

I'm using django-tastypie and I need to create classes like this from my django models: ``` class MyModelResource(ModelResource): class Meta: queryset = MyModel.objects.all() allowed_methods = ['get'] ``` Since I have a lot of models in my django app I don't want to repeat myself, and use type() function instead to create all that resource classes. The problem is I don't know how to deal with this inner "Meta" class. Can you give me an example of how to dynamically create a class with inner class using type()?

Original source