Ich erstelle eine Django-App, die einige Vererbung in seinem Modell verwendet, hauptsächlich weil ich alles eine UUID und eine Referenz zuweisen muss, damit ich weiß, welche Klasse es war. Hier ist eine vereinfachte Version der Basisklasse:Vererbung und Factory-Funktionen in Python und Django
class BaseElement(models.Model):
uuid = models.CharField(max_length=64, editable=False, blank=True, default=lambda:unicode(uuid4()))
objmodule = models.CharField(max_length=255, editable=False, blank=False)
objclass = models.CharField(max_length=255, editable=False, blank=False)
class ChildElement(BaseElement):
somefield = models.CharField(max_length=255)
Ich mag würde, um sicherzustellen, dass objmodule, objclass und UUID automatisch eingestellt werden. Ich habe von gelernt, dass es eine schlechte Idee ist, das zu tun, indem ich meinen eigenen Erbauer schreibe, und dass ich besser bin, eine Fabrikfunktion zu schreiben. So, jetzt mein BaseElement und ChildElement sieht so aus:
class BaseElement(models.Model):
uuid = models.CharField(max_length=64, editable=False, blank=True, default=lambda:unicode(uuid4()))
objmodule = models.CharField(max_length=255, editable=False, blank=False)
objclass = models.CharField(max_length=255, editable=False, blank=False)
def set_defaults(self):
self.objmodule = unicode(self.__class__.__module__)
self.objclass = unicode(self.__class__.__name__)
self.uuid = unicode(uuid4())
class ChildElement(BaseElement):
somefield = models.CharField(max_length=255)
@staticmethod
def create(*args, **kwargs):
ce = ChildElement(*args, **kwargs)
ce.set_defaults()
return ce
Dies funktioniert. Ich kann ChildElement.create(somefield="foo")
anrufen und ich werde ein passendes Objekt mit uuid
, objmodule
und objclass
Felder richtig eingestellt bekommen. Wie auch immer, wenn ich durch gehe und mehr Klassen wie ChildElement2
und ChildElement3
erstelle, finde ich, dass ich die genau gleiche statische Fabrikfunktion einfüge. Das schimpft auf mich, weil die Code-Duplikation schlecht ist.
Mit normalen Methoden würde ich nur die create
Factory-Funktion in BaseElement
einfügen, aber ich kann das hier nicht tun, weil ich kein Handle zu sich selbst (weil es noch nicht erstellt wurde) zu bekommen Informationen über die Klasse des Objekts, das die Methode aufgerufen hat.
Gibt es eine Möglichkeit, dass ich dieses Werk in die BaseElement
Klasse migrieren können, damit ich diesen Code nicht überall vervielfältigen müssen und haben es immer noch so ist es automatisch die Werte von uuid
setzt objmodule
und objclass
?
Genau das habe ich gesucht. Danke, dass du mich an '@ classmethod' erinnert hast. Es ist nicht etwas, was ich sehr oft benutze. – Pridkett
In Python gibt es selten einen guten Anwendungsfall für '@ staticmethod' - das ist der, den Sie wahrscheinlich seltener verwenden sollten, wenn überhaupt. Oft ist etwas, wenn es sich nicht um eine '@ Klassenmethode handelt, als einfache Top-Level-Funktion in einem Modul geeignet. –