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

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

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

您能否举一个示例,说明如何使用type()与内部类一起动态创建一个类?

最佳答案

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返回绑定(bind)的方法。

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

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

你是绝对正确的
super(self.__class_, self).mymethod()

是错的。这将破坏有关super的所有好处。如果将MyModelResource进行子类化,并且该子类的一个实例将调用mymethod,则Python将陷入无限循环。

09-28 09:25