Angenommen, ich habe eine Klasse mit einem Konstruktor (oder einer anderen Funktion), die eine variable Anzahl von Argumenten verwendet und diese dann bedingt als Klassenattribute festlegt.
Ich könnte sie manuell einstellen, aber es scheint, dass variable Parameter in Python häufig genug sind, dass es dafür eine gemeinsame Sprache geben sollte. Aber ich bin mir nicht sicher, wie ich das dynamisch machen soll.
Ich habe ein Beispiel mit eval, aber das ist kaum sicher. Ich möchte wissen, wie ich das richtig machen kann - vielleicht mit Lambda?
class Foo:
def setAllManually(self, a=None, b=None, c=None):
if a!=None:
self.a = a
if b!=None:
self.b = b
if c!=None:
self.c = c
def setAllWithEval(self, **kwargs):
for key in **kwargs:
if kwargs[param] != None
eval("self." + key + "=" + kwargs[param])
pip install attrs
Dekorieren Sie einfach Ihre Klasse mit@attr.s
und setzen Sie die Argumente wiea = attr.ib(); b = attr.ib()
usw. Lesen Sie hier mehr .Antworten:
Sie können das
__dict__
Attribut (das die Klassenattribute in Form eines Wörterbuchs darstellt) mit den Schlüsselwortargumenten aktualisieren :dann kannst du:
und mit so etwas wie:
Sie können die Schlüssel vorher filtern (verwenden Sie
iteritems
anstelle von,items
wenn Sie noch Python 2.x verwenden).quelle
self.__dict__.update(locals())
auch Positionsargumente kopieren.kwargs[0]
statt nurkwargs
? Kannkwargs
sogar ein ganzzahliger Schlüssel haben? Ich bin mir ziemlich sicher, dass es Strings sein müssen.Sie können die
setattr()
Methode verwenden:Es gibt eine analoge
getattr()
Methode zum Abrufen von Attributen.quelle
.getattr()
? Oder können Sie mit auf die Attribute zugreifenFoo.key
?Foo.attrname
. Ich glaube, ich habe nur darauf hingewiesen, dass diegetattr
Methode existiert. Dies ist auch nützlich, wenn Sie einen Standardwert angeben möchten, wenn das angegebene Attribut nicht verfügbar ist.Die meisten Antworten hier bieten keine gute Möglichkeit, alle zulässigen Attribute auf nur einen Standardwert zu initialisieren. Um die Antworten von @fqxp und @mmj zu ergänzen :
quelle
False
. Guter Punkt!Ich schlage vor , eine Änderung der Antwort des fqxp , die, zusätzlich zu den erlaubten Attribute Sie festlegen können Standardwerte für Attribute:
Dies ist Python 3.x-Code. Für Python 2.x benötigen Sie mindestens eine Anpassung
iteritems()
anstelle vonitems()
.quelle
Noch eine Variante basierend auf den hervorragenden Antworten von mmj und fqxp . Was ist, wenn wir wollen?
Mit "direkt" meine ich das Vermeiden eines fremden
default_attributes
Wörterbuchs.Kein großer Durchbruch, aber vielleicht nützlich für jemanden ...
BEARBEITEN: Wenn unsere Klasse
@property
Dekoratoren verwendet, um "geschützte" Attribute mit Get- und Setzern zu kapseln, und wenn wir diese Eigenschaften mit unserem Konstruktor festlegen möchten, möchten wir dieallowed_keys
Liste möglicherweise mit den folgenden Werten erweiterndir(self)
:Der obige Code schließt aus
dir()
(Ausschluss basierend auf dem Vorhandensein von "__") unddir()
deren Name am Ende eines Attributnamens (geschützt oder anderweitig) nicht gefunden wird__dict__.keys()
, behält wahrscheinlich nur mit @property dekorierte Methoden bei.Diese Bearbeitung ist wahrscheinlich nur für Python 3 und höher gültig.
quelle
Ich habe die Klasse aufgerufen,
SymbolDict
weil es sich im Wesentlichen um ein Wörterbuch handelt, das Symbole anstelle von Zeichenfolgen verwendet. Mit anderen Worten, Sie tun esx.foo
statt,x['foo']
aber unter der Decke ist es wirklich dasselbe.quelle
Die folgenden Lösungen
vars(self).update(kwargs)
oderself.__dict__.update(**kwargs)
sind nicht robust, da der Benutzer jedes Wörterbuch ohne Fehlermeldungen eingeben. Wenn ich überprüfen muss, ob der Benutzer die folgende Signatur einfügt ('a1', 'a2', 'a3', 'a4', 'a5'), funktioniert die Lösung nicht. Darüber hinaus sollte der Benutzer in der Lage sein, das Objekt durch Übergeben der "Positionsparameter" oder der "Kay-Wert-Paar-Parameter" zu verwenden.Daher schlage ich die folgende Lösung unter Verwendung einer Metaklasse vor.
quelle
Sie könnten eine bessere Lösung sein, aber mir fällt Folgendes ein:
quelle
Dieser ist der einfachste über Larsks
mein Beispiel:
quelle
kwargs
ist ein Wörterbuch mit Schlüsselwortargumenten unditems()
eine Methode, die eine Kopie der Paarliste des Wörterbuchs zurückgibt(key, value)
.Ich vermute, dass es in den meisten Fällen besser ist, benannte Argumente zu verwenden (für besseren selbstdokumentierenden Code), so dass es ungefähr so aussehen könnte:
quelle
for key, value in (a, b, c)