Ist selbst .__ dict __. Update (** kwargs) gut oder schlecht?
In Python, sagen, ich habe einige Klasse Kreis erbt von Shape. Form muss x - und y-Koordinaten, und, darüber hinaus, Kreis braucht einen radius. Ich möchte in der Lage sein zu initialisieren Kreis von etwas wie,
c = Circle(x=1., y=5., r=3.)
Kreis erbt von Form, also muss ich verwenden benannte Argumente zu __init__
weil unterschiedliche Klassen erfordern verschiedene Konstruktoren. Ich könnte manuell einstellen x, y, und r.
class Shape(object):
def __init__(self, **kwargs):
self.x = kwargs['x']
self.y = kwargs['y']
class Circle(Shape):
def __init__(self, **kwargs):
super(Circle, self).__init__(**kwargs)
self.r = kwargs['r']
oder, ich hätte die Attribute von meinem Kreis-set automatisch mit self.__dict__.update(kwargs)
class Shape(object):
def __init__(self, **kwargs):
self.__dict__.update(**kwargs)
class Circle(Shape):
def __init__(self, **kwargs):
super(Circle, self).__init__(**kwargs)
Dies hat den Vorteil, dass es weniger code und ich brauche nicht zu erhalten boilerplate wie self.foo = kwargs['foo']
. Der Nachteil ist, dass es nicht offensichtlich ist, welche Argumente benötigt werden, für Kreis. Ist dies als ein cheat oder ist das guter Stil (solange die Schnittstelle auf den Kreis ist gut dokumentiert)?
Dank, jeder, für Ihre durchdachten Antworten. Die self.__dict__.update(**kwargs)
hack wurde für mich nützlich, im Experimentieren mit dem organisieren von meinem code, aber ich werde dafür sorgen, dass ich ersetzen, dass mit ordnungsgemäß übergeben Argumente ausdrücklich und tun klar Fehlerkontrolle in der Produktion code.
self
. InformationsquelleAutor der Frage Alex Szatmary | 2012-03-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Und das ist es. Verwenden Sie nicht
**kwargs
wenn Sie nicht wirklich brauchen.Wenn Sie die Wahl haben zwischen dem schreiben eines einfachen, verständlichen code und Kopfschmerzen-code + schöne docstrings, die Sie eigentlich nicht haben eine Wahl, Sie einfach gehen und schreiben von einfachen, selbst-dokumentierte code:)
InformationsquelleAutor der Antwort Roman Bodnarchuk
Ich würde sagen, dass die erste Methode ist definitiv vorzuziehen, weil explizit ist besser als implizit.
Überlegen, was passieren würde, wenn Sie einen Tippfehler gemacht, bei der Initialisierung einen Kreis, so etwas wie
Circle(x=1., y=5., rr=3.)
. Sie wollen, um zu sehen, dieser Fehler sofort, das würde nicht passieren, mit__dict__.update(kwargs)
.InformationsquelleAutor der Antwort Andrew Clark
Wenn Sie möchten, um automatisch zuweisen, ich schlage die folgende Vorgehensweise vor:
welche, in Bezug auf Stil, irgendwo zwischen schreiben es explizit und hacken es selbst mit
self.__dict__
.InformationsquelleAutor der Antwort Simeon Visser
Wenn Sie wollte, dass es mehr offensichtlich, Sie hätte
Circle.__init__
führen einige sanity checks auf die Argumente. Vermutlich würde Sie überprüfen, um sicherzustellen, dass alle Argumente, die dort sind, und gegebenenfalls erhöhen Fehler für sinnlose Argumente.Wahrscheinlich könnte man auch einen Dekorateur oder Helfer-Funktion in
Shape
um dies für Sie tun. So etwas wie dieses:.check
umgesetzt würde, inShape
und im wesentlichen nur überprüft, ob alle Argumente inkwargs
, und möglicherweise, dass keine extra-sind (sorry, kein code für die one - Sie können herausfinden, auf Ihre eigenen). Sie können sogar Unterklassen überladen, um zu prüfen, für optionale Argumente, die Sie verarbeiten wollen, anders als andere Argumente (d.h. geben Sie einen default-Wert, die sonst nicht zugeordnet werden inShape.__init__
.Andernfalls, wenn Sie ein Dokument in Ihrem interface, und es funktioniert so, wie es ist dokumentiert, es ist immer in Ordnung. Alles, was Sie tun, um es so funktionieren, wie wir "erwarten" es (das werfen von Ausnahmen für falsche Argumente), ist ein bonus.
InformationsquelleAutor der Antwort Chris Lutz