Was ist die richtige Verwendung **kwargs
in Python, wenn es um Standardwerte geht?
kwargs
gibt ein Wörterbuch zurück, aber wie lassen sich Standardwerte am besten festlegen, oder gibt es einen? Soll ich nur als Wörterbuch darauf zugreifen? Get-Funktion verwenden?
class ExampleClass:
def __init__(self, **kwargs):
self.val = kwargs['val']
self.val2 = kwargs.get('val2')
Eine einfache Frage, für die ich keine guten Ressourcen finden kann. Die Leute machen es auf unterschiedliche Weise in Code, den ich gesehen habe, und es ist schwer zu wissen, was sie verwenden sollen.
__init__()
. Kann jemand erklären, warum dies eine fusselfreie Übertretung ist?self.__dict__update(**kwargs)
Methoden neu definieren und andere Fehler verursachen kannWährend die meisten Antworten sagen, dass z.
ist das gleiche wie"
das ist nicht wahr. Im letzteren Fall
f
kann als aufgerufen werdenf(23, 42)
, während im ersteren Fall nur benannte Argumente akzeptiert werden - keine Positionsaufrufe. Oft möchten Sie dem Anrufer maximale Flexibilität gewähren, und daher ist die zweite Form, wie die meisten Antworten behaupten, vorzuziehen. Dies ist jedoch nicht immer der Fall. Wenn Sie viele optionale Parameter akzeptieren, von denen normalerweise nur wenige übergeben werden, ist es möglicherweise eine hervorragende Idee (Vermeidung von Unfällen und unlesbarem Code an Ihren Anrufstellen!), Die Verwendung benannter Argumente zu erzwingen -threading.Thread
ist ein Beispiel. Das erste Formular ist, wie Sie das in Python 2 implementieren.Das Idiom ist so wichtig, dass es in Python 3 jetzt eine spezielle unterstützende Syntax hat: Jedes Argument nach einem einzelnen
*
in derdef
Signatur ist nur ein Schlüsselwort, dh es kann nicht als Positionsargument übergeben werden, sondern nur als benanntes. In Python 3 können Sie Folgendes wie folgt codieren:In Python 3 können Sie sogar Argumente nur mit Schlüsselwörtern verwenden, die nicht optional sind (solche ohne Standardwert).
Python 2 hat jedoch noch lange Jahre produktiven Lebens vor sich. Vergessen Sie daher nicht die Techniken und Redewendungen, mit denen Sie wichtige Designideen in Python 2 implementieren können, die direkt in der Sprache in Python 3 unterstützt werden!
quelle
Ich schlage so etwas vor
Und dann verwenden Sie die Werte wie Sie wollen
dictionaryA.update(dictionaryB)
Fügt den InhaltdictionaryB
zumdictionaryA
Überschreiben doppelter Schlüssel hinzu.quelle
for key in options: self.__setattr__(key, options[key])
und ich bin gut zu gehen. :)Das würdest du tun
oder
Wenn Sie verwenden
pop
, können Sie überprüfen, ob falsche Werte gesendet wurden, und die entsprechenden Maßnahmen ergreifen (falls vorhanden).quelle
.pop
, dass Sie überprüfen können, ob falsche Werte gesendet wurden?kwargs
aus einem bestimmten Grund erfassen .default_value
übergebenen zurück? Und entfernt diesen Schlüssel danach?Die Verwendung von ** kwargs und Standardwerten ist einfach. Manchmal sollten Sie jedoch überhaupt keine ** kwargs verwenden.
In diesem Fall nutzen wir ** kwargs nicht wirklich optimal.
Das obige ist ein "warum sich die Mühe machen?" Erklärung. Es ist das gleiche wie
Wenn Sie ** kwargs verwenden, bedeutet dies, dass ein Schlüsselwort nicht nur optional, sondern auch bedingt ist. Es gibt komplexere Regeln als einfache Standardwerte.
Wenn Sie ** kwargs verwenden, meinen Sie normalerweise etwas wie das Folgende, bei dem einfache Standardeinstellungen nicht zutreffen.
quelle
Da dies verwendet
**kwargs
wird, wenn die Anzahl der Argumente unbekannt ist, warum nicht?quelle
Hier ist ein anderer Ansatz:
quelle
get_form_kwargs()
. B. ). ccbv.co.uk/projects/Django/1.5/django.views.generic.edit/…get_form()
Methode zeigt, wie Sie Schlüsselwortargumente ausführlich erhalten, indem Sie auf eine andere Methode zurückgreifen (get_form_kwargs
wie oben erwähnt). Es instanziiert das Formular wie folgt :form_class(**self.get_form_kwargs())
.get_form_kwargs()
in einer Unterklassenansicht zu überschreiben und kwargs basierend auf einer bestimmten Logik hinzuzufügen / zu entfernen. Aber das ist für ein Django-Tutorial.Ich denke, der richtige Weg, um
**kwargs
in Python zu verwenden, wenn es um Standardwerte geht, ist die Verwendung der Wörterbuchmethodesetdefault
, wie unten angegeben:Auf diese Weise werden Benutzer verwendet, die im Schlüsselwort 'val' oder 'val2' übergeben
args
. Andernfalls werden die festgelegten Standardwerte verwendet.quelle
Sie könnten so etwas tun
quelle
Im Anschluss an @srhegde Vorschlag der Verwendung von setattr :
Diese Variante ist nützlich, wenn von der Klasse erwartet wird, dass sie alle Elemente in unserer
acceptable
Liste enthält.quelle
Wenn Sie dies mit * args kombinieren möchten, müssen Sie * args und ** kwargs am Ende der Definition behalten.
Damit:
quelle
@AbhinavGupta und @Steef schlugen die Verwendung vor
update()
, was ich für die Verarbeitung großer Argumentlisten sehr hilfreich fand:Was ist, wenn wir überprüfen möchten, ob der Benutzer keine falschen / nicht unterstützten Argumente übergeben hat? @VinaySajip wies darauf hin, dass
pop()
die Liste der Argumente iterativ verarbeitet werden kann. Dann sind alle verbleibenden Argumente falsch. Nett.Hier ist eine andere Möglichkeit, dies zu tun, wobei die einfache Syntax der Verwendung beibehalten wird
update()
:unknown_args
ist a undset
enthält die Namen von Argumenten, die in den Standardeinstellungen nicht vorkommen.quelle
Eine andere einfache Lösung für die Verarbeitung unbekannter oder mehrerer Argumente kann sein:
quelle
** kwargs gibt die Freiheit, eine beliebige Anzahl von Schlüsselwortargumenten hinzuzufügen. Man kann eine Liste von Schlüsseln haben, für die man Standardwerte festlegen kann. Das Festlegen von Standardwerten für eine unbestimmte Anzahl von Schlüsseln erscheint jedoch nicht erforderlich. Schließlich kann es wichtig sein, die Schlüssel als Instanzattribute zu haben. Also würde ich das wie folgt machen:
quelle