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
Die innere Klasse, Meta
, ist nur ein weiteres Attribut so weit wie MyModelResource
betrifft.
Methoden sind auch so weit nur Attribute wie MyModelResource
betroffen ist. Tatsächlich definieren Sie eine Funktion in MyModelResource.__dict__
, und der Python-Attribut-Lookup-Mechanismus verursacht inst.mymethod
, um eine gebundene Methode zurückzugeben.
Es gibt kein Problem zu MyModelResource
im super
Aufruf bezieht
super(MyModelResource, self).mymethod()
vor MyModelResource
definiert ist, weil Name Lookups zur Laufzeit durchgeführt wird, nicht zu dem Zeitpunkt mymethod
definiert ist.
Sie sind absolut richtig, dass
super(self.__class_, self).mymethod()
falsch ist. Dies verderbt alles, was gut ist über super
. Wenn MyModelResource
Unterklasse sein sollte und eine Instanz der Unterklasse mymethod
aufrufen sollte, würde Python in eine Endlosschleife fallen.
Dies ist die richtige Antwort. Was nun, wenn ich eine Methode definieren muss, die super() aufruft? Ich möchte vermeiden, super (selbst .__ class__, self) zu schreiben, weil anscheinend keine gute Idee ist ... – mnowotka
das Problem ist, ich weiß nicht, Name der Klasse im Moment der Definition der Methode. In meinem Fall sieht die Erstellung der Klasse folgendermaßen aus: type (modelClass .__ class __.__ name__ + "Resource", (ModelResource,), {"Meta" ... also kann ich in der Methode nicht mit dem Namen darauf verweisen. – mnowotka
Okay, so 'mymethod' kann erst definiert werden, nachdem'MyModelResource' definiert wurde.In diesem Fall benutze einen Klassendekorator.Ich habe als Beispiel den Klassendekorator' add_mymethod' hinzugefügt. – unutbu