Wie vermeide ich das "self.x = x; self.y = y; self.z = z "Muster in __init__?
Sehe ich Muster, wie
def __init__(self, x, y, z):
...
self.x = x
self.y = y
self.z = z
...
ziemlich Häufig, oft mit viel mehr Parametern. Ist es ein guter Weg, um zu vermeiden, diese Art von ermüdender Wiederholung? Sollte die Klasse Erben, von namedtuple
statt?
InformationsquelleAutor der Frage MaxB | 2016-02-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dekorateur Lösung, die hält die Signatur:
InformationsquelleAutor der Antwort Siphor
BEARBEITEN
Es scheint, dass einige Leute besorgt über die Darstellung dieser Lösung, so werde ich Ihnen eine sehr klare Haftungsausschluss. Sie sollten nicht diese Lösung. Ich nur als information, damit Sie wissen, dass die Sprache in der Lage. Der rest der Antwort ist nur zeigen, Funktionen der Sprache, nicht befürworten, mit Ihnen auf diese Weise.
URSPRÜNGLICHE ANTWORT
Gibt es nicht wirklich, nichts falsch mit explizit kopieren Parameter in den Parametern. Wenn man zu viele Parameter im ctor, ist es manchmal als ein code smell und vielleicht solltest du die params in ein weniger Objekte. Andere Zeiten, es ist notwendig und es ist nichts falsch mit ihm. Eh, tut es explizit ist der Weg zu gehen.
Aber, da Sie Fragen, WIE es getan werden kann (und nicht, ob es getan werden sollte), dann eine Lösung ist:
InformationsquelleAutor der Antwort gruszczy
Wie andere erwähnt haben, die Wiederholung ist nicht schlecht, aber in einigen Fällen namedtuple kann eine gute Passform für diese Art von Problem. Dies vermeidet die Verwendung von locals() oder kwargs, die in der Regel eine schlechte Idee.
Habe ich begrenzt, aber Sie können die Erben eine namedtuple, wie mit jedem anderen Objekt (Beispiel, Fortsetzung):
InformationsquelleAutor der Antwort A Small Shell Script
explizit ist besser als implizit ...
so sicher, Sie könnten machen es kurz:
Die bessere Frage ist, sollte Sie?
... , sagte Sie, wenn Sie möchten, eine benannte Tupel ich würde empfehlen, mit einem namedtuple (denken Sie daran Tupel haben bestimmte Bedingungen, die mit Ihnen verbunden) ... vielleicht wollen Sie ein ordereddict oder auch nur ein dict ...
InformationsquelleAutor der Antwort Joran Beasley
Erweitern
gruszczy
s Antwort, die ich verwendet habe ein Muster wie:Ich mag diese Methode, weil es:
super().__init(...)
)X.__init__
Vor Python-3.6, dies gibt keine Kontrolle über die Reihenfolge, in der die Attribute sind gesetzt, das könnte ein problem werden, wenn einige Attribute sind Eigenschaften, die mit Set-Methoden, die den Zugriff auf andere Attribute.
Könnte es wahrscheinlich besser noch ein bisschen, aber ich bin der einzige Benutzer an meinem eigenen code, so bin ich nicht besorgt über jede form von input-Hygiene. Vielleicht ein
AttributeError
wäre passender.InformationsquelleAutor der Antwort gerrit
Könnten Sie auch tun:
Natürlich müssten Sie importieren die
inspect
Modul.InformationsquelleAutor der Antwort zondo
Dies ist eine Lösung, die ohne zusätzliche Importe.
Hilfsfunktion
Eine kleine helper-Funktion macht es bequemer und wiederverwendbar:
Anwendung
Müssen Sie rufen es mit
locals()
:Test
Ausgabe:
Ohne änderung
locals()
Wenn Sie nicht mögen, zu ändern
locals()
verwenden Sie diese version:InformationsquelleAutor der Antwort Mike Müller
Meine 0.02$. Es ist sehr nah an Joran Beasley Antwort, aber eleganter:
Zusätzlich, Mike Müller, die Antwort (das beste nach meinem Geschmack ist), kann reduziert werden mit dieser Technik:
Und die rufen
auto_init(locals())
von Ihrem__init__
InformationsquelleAutor der Antwort bgusach
Eine interessante Bibliothek, die dies erledigt (und vermeidet eine Menge von anderen vorformulierten) ist attrs. Dein Beispiel, zum Beispiel, könnte reduziert werden, um diese (angenommen, die Klasse genannt wird
MyClass
):Brauchen Sie nicht einmal eine
__init__
Methode mehr, es sei denn, er tut andere Dinge als gut. Hier ist eine schöne Einleitung durch die Glyphe Lefkowitz.InformationsquelleAutor der Antwort RafG
Es ist ein natürlicher Weg, Dinge zu tun, die in Python. Versuchen Sie nicht, etwas zu erfinden, klüger zu werden, wird es zu übermäßig cleveren code, dass niemand in Ihrem team verstehen. Wenn Sie wollen ein team-player, dann schreiben halten es auf diese Weise.
InformationsquelleAutor der Antwort Peter Krumins
Python 3.7 ab
In Python 3.7, können Sie (ab -) Nutzung der
dataclass
Dekorateur, erhältlich von derdataclasses
Modul. Aus der Dokumentation:Wenn Ihre Klasse ist groß und Komplex, es kann unangemessen zu verwenden
dataclass
. Ich Schreibe dies am Tag des release von Python 3.7.0, so Nutzungsmuster sind noch nicht etabliert.InformationsquelleAutor der Antwort gerrit