getattr-und setattr auf verschachtelte Objekte?
dies ist wahrscheinlich ein einfaches problem, so hopefuly Ihre leicht, jemanden darauf hinweisen, meine Fehler sind, oder ob dies überhaupt möglich ist.
Ich habe ein Objekt, das mehrere Objekte als Eigenschaften. Ich möchte in der Lage sein, dynamisch die Eigenschaften dieser Objekte wie so:
class Person(object):
def __init__(self):
self.pet = Pet()
self.residence = Residence()
class Pet(object):
def __init__(self,name='Fido',species='Dog'):
self.name = name
self.species = species
class Residence(object):
def __init__(self,type='House',sqft=None):
self.type = type
self.sqft=sqft
if __name__=='__main__':
p=Person()
setattr(p,'pet.name','Sparky')
setattr(p,'residence.type','Apartment')
print p.__dict__
Ausgabe:
{'pet': <main.Haustier Objekt an 0x10c5ec050>, 'residence': <main.Residence Objekt in 0x10c5ec0d0>, 'pet.name': 'Sparky', 'residence'.type': 'Wohnung'}
Wie Sie sehen können, eher dann mit dem name-Attribut auf das Haustier-Objekt der person, der ein neues Attribut "pet.name" erstellt.
Kann ich nicht angeben, person.pet setattr, weil verschiedene Kind-Objekte werden durch die gleiche Methode, die in der Analyse von text und ausfüllen der Objekt-Attribute, wenn/wenn Sie eine entsprechende Taste zu finden ist.
Gibt es eine einfache/Baujahr Art und Weise, dies zu erreichen?
Oder vielleicht brauche ich, um schreiben Sie eine rekursive Funktion zum Parsen der Zeichenfolge und der Aufruf von getattr mehrere Male, bis die notwendigen Kind-Objekt gefunden und dann call setattr auf das Gefundene Objekt?
Danke!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Könnten Sie
functools.reduzieren
:rgetattr
undrsetattr
sind drop-in-Ersatz fürgetattr
undsetattr
,die kann auch mit gepunkteten
attr
strings.rgetattr
dass unterstützt auch diedefault
parameter?default
parameter. Ich wünschte, ich könnte machen es ein wenig einfacher, aber c ' est la vie.AttributeError
Umgang dortFür ein Elternteil und ein Kind:
Dies ist einfacher als die anderen Antworten, die für diesen speziellen Anwendungsfall.
Machte ich eine einfache version, basierend auf ubntu Antwort genannt magicattr, das funktioniert auch auf attrs, Listen und dicts durch analysieren und zu Fuß den ast.
Z.B. mit dieser Klasse:
Können Sie dies tun,
Es auch nicht lassen, die Sie/jemanden rufen Funktionen oder weisen Sie einen Wert, da es sich nicht mit eval oder ermöglichen Zuweisen/Call-Knoten.
unutbu Antwort (https://stackoverflow.com/a/31174427/2683842) hat einen "bug". Nach
getattr()
ausfällt und ersetzt wird durchdefault
es weiterhin aufrufengetattr
aufdefault
.Beispiel:
rgetattr(object(), "nothing.imag", 1)
sollte gleich1
meiner Meinung nach, aber es gibt0
:getattr(object(), 'nothing', 1)
== 1.getattr(1, 'imag', 1)
== 0 (da 1 ist real und hat keine komplexe Komponente).Lösung
Ich geändert rgetattr zurück
default
an dem fehlenden Attribut:*default
wird leer, wenn kein Standardwert festgelegt wurde, also einif default
zurückFalse
. Wenndefault
hat ein element, dann können wir zurückgeben, da der default-Wert. In der Regel wird dies gelöst durch die Initialisierung ein Objekt und benennen es_DEFAULT
oder etwas ähnliches, und dass die kwargdefault=_DEFAULT
, aber diese Lösung ist doch viel einfacher, wenn etwas nicht so offensichtlich, dass jemand noch nicht gesehen.Ok, so dass während der Eingabe die Frage, die ich hatte eine Idee, wie dies zu tun, und es scheint gut zu funktionieren. Hier ist, was ich kam mit:
Ich denke, das löst meine Frage, aber ich bin immer noch neugierig, wenn es gibt ein besserer Weg, dies zu tun?
Ich glaube, das hat etwas ziemlich Häufig in OOP und python, also ich bin überrascht, gatattr und setattr nicht unterstützen das nativ.
final_attribute
können mehr als einmal auftreten. Zum Beispielp.foo.foo
legal ist. So ist die Bedingungpart == final_attribute
auslösen können, sind zu früh.