python用内部类动态创建类
Posted
技术标签:
【中文标题】python用内部类动态创建类【英文标题】:python dynamically create class with inner class 【发布时间】:2012-11-15 07:30:31 【问题描述】:我正在使用 django-tastypie,我需要从我的 django 模型中创建这样的类:
class MyModelResource(ModelResource):
class Meta:
queryset = MyModel.objects.all()
allowed_methods = ['get']
由于我的 django 应用程序中有很多模型,我不想重复自己,而是使用 type() 函数来创建所有资源类。问题是我不知道如何处理这个内部“元”类。
你能给我举个例子,说明如何使用 type() 动态创建具有内部类的类吗?
【问题讨论】:
【参考方案1】: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
就MyModelResource
而言,内部类Meta
只是另一个属性。
就MyModelResource
而言,方法也只是属性。其实你在MyModelResource.__dict__
中定义了一个函数,Python的属性查找机制
导致inst.mymethod
返回一个绑定的方法。
super
调用中引用MyModelResource
没有问题
super(MyModelResource, self).mymethod()
在定义 MyModelResource
之前,因为名称查找是在运行时执行的,而不是在定义 mymethod
时执行的。
你说的很对
super(self.__class_, self).mymethod()
错了。这将破坏super
的所有优点。如果 MyModelResource
被子类化,并且子类的一个实例要调用 mymethod
,那么 Python 将陷入无限循环。
【讨论】:
这是正确答案。现在,如果我必须在内部定义调用 super() 的方法怎么办?我想避免写 super(self.__class__, self) 因为显然不是一个好主意... 问题是在定义方法的那一刻我不知道类的名称。在我的情况下,类的创建如下所示: type(modelClass.__class__.__name__ + "Resource",(ModelResource, ), "Meta"... 所以我不能在方法中按名称引用它。 好的,所以mymethod
在定义 MyModelResource
之前无法定义。在这种情况下,请使用类装饰器。我添加了类装饰器 add_mymethod
作为示例。以上是关于python用内部类动态创建类的主要内容,如果未能解决你的问题,请参考以下文章