python用内部类动态创建类

时间:2012-11-27 16:08:52

标签: python class metaprogramming tastypie metaclass

我正在使用django-tastypie,我需要从我的django模型中创建这样的类:

class MyModelResource(ModelResource):
    class Meta:
        queryset = MyModel.objects.all()
        allowed_methods = ['get']

由于我的django应用程序中有很多模型,我不想重复自己,而是使用type()函数来创建所有资源类。问题是我不知道如何处理这个内在的“元”类。

您能举例说明如何使用type()动态创建具有内部类的类吗?

1 个答案:

答案 0 :(得分:11)

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

Meta而言,内部类MyModelResource只是另一个属性。


MyModelResource而言,方法也只是属性。实际上,您在MyModelResource.__dict__中定义了函数,以及Python属性查找机制 导致inst.mymethod返回绑定的方法

MyModelResource电话

中引用super没有问题
super(MyModelResource, self).mymethod()

在定义MyModelResource之前,因为名称查找是在运行时执行的,而不是在定义mymethod时执行。


你绝对正确

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

错了。这会破坏super的所有优点。如果MyModelResource被子类化,并且子类的实例要调用mymethod,那么Python将陷入无限循环。