2012-11-27 9 views
5

内部クラスを持つクラスを作成し、私は私のDjangoのモデルから、このようなクラスを作成する必要があります。私は私のDjangoのアプリIドン中のモデルの多くを持っているのでPythonは動的に私はジャンゴ-tastypieを使用してい

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

を自分自身を繰り返したいのではなく、代わりにtype()関数を使用してすべてのリソースクラスを作成します。問題は、この "Meta"クラスに対処する方法がわからないことです。

type()を使用して内部クラスを持つクラスを動的に作成する方法の例を教えてください。

答えて

7
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には、のメソッドが返されます。名前検索ではありませんmymethodが定義されているときに、実行時に実行されるため

は、MyModelResource

super(MyModelResource, self).mymethod() 

が定義されているsuper呼び出しでMyModelResourceを参照問題ありません。


あなたは

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

が間違っていることが絶対に正しいです。これは、すべての良いことを台無しにする約superMyModelResourceがサブクラス化され、サブクラスのインスタンスがmymethodを呼び出す場合、Pythonは無限ループに陥ります。

+0

これは正解です。今、super()を呼び出すメソッドを定義しなければならない場合はどうしたらいいですか?私は明らかに良いアイデアではないので、スーパー(自己.__ class__、自己)を書くことを避けたい... – mnowotka

+0

問題は私がメソッドを定義する瞬間にクラスの名前を知らないです。私の場合、クラスの作成は次のようになります:type(modelClass .__ class __.__ name__ + "Resource"、(ModelResource)、{"Meta" ...}このメソッドの名前で参照することはできません。 – mnowotka

+0

'mymethod'は' MyModelResource'が定義されるまで定義できません。その場合はクラスデコレータを使用します。クラスデコレータ 'add_mymethod'を例として追加しました。 – unutbu

関連する問題