Seite 1 von 1
in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 12:15
von Goswin
Ich möchte ein Objekt "in place" verändern, aber wie man leicht sehen kann, ist die Vorgehensweise in folgendem
Beispiel falsch:
Code: Alles auswählen
class IList(list):
def transform(self):
#self.sort() #wie gewuenscht, aber *nicht immer vorhanden*
self = sorted(self) #veraendert self nicht wirklich
print("intern:",self) #gibt gewuenschtes Ergebnis aus
Code: Alles auswählen
ll = IList([4,2,5,3])
print(ll)
ll.transform()
print(ll) #gibt weiterhin [4,2,5,3] aus
Nicht immer soll ein Objekt bloß geordnet werden, und bei
längeren Abänderungen ist es in der Regel unvermeidlich, das gewünschte Ergebnis irgendwo zwischenzuspeichern. Das soll der Anwender aber nicht merken: das Objekt, dem die Methode angehört, soll automatisch abgeändert werden.
Wie macht man das? Oder macht man das nie?
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 12:40
von /me
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 13:09
von deets
Warum nicht "self.sort", die Methode, die Listen in-place sortiert?
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 13:40
von Rekrul
@Goswin
... ist keine in-place Sortierung. So wird dem Programmierer lediglich 'xy = xy.transform()' erspart. Um richtig 'in-place' zu sortieren musst du schon self.sort verwenden. Sollte sort nicht immer vorhanden sein, dann musst du wohl selbst 'in-place' sortieren.
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 13:51
von snafu
Rekrul hat geschrieben:@Goswin
... ist keine in-place Sortierung.
Wobei vom TE wohl eher der Erhalt der Objektidentität gemeint war und weniger das tatsächliche interne Vorgehen. Von daher bietet es sich durchaus an, den *Inhalt*, nicht aber das Objekt an sich zu erneuern. Wozu das gut ist bzw warum nicht einfach grundsätzlich von `list` geerbt wird, ist natürlich eine andere Frage...
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 14:25
von deets
@snafu
Es wird ja von list geerbt.
Wobei ich erst jetzt den "nicht immer vorhanden" Kommentar sehe - und nicht verstehe...
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 15:05
von Goswin
deets hat geschrieben:Wobei ich erst jetzt den "nicht immer vorhanden" Kommentar sehe - und nicht verstehe...
Tja, es ist schon mal schwer, den Lesern eine Frage umfassend und gleichzeitig einfach zu gestalten.
Es geht mir nicht ums Ordnen einer Liste, es geht mir um eines meiner komplizierteren Objekte, dass ich abändern will. Meine Methode dafür ist viel zu lang als dass ihr sie wirklich lesen wollt, und 99% davon ist für die Fragestellung völlig irrelevant. In dieser Methode erstelle ich ein neues Objekt, das den Platz des ursprünglichen Objektes einnehmen soll. Dem Anwender will ich nur die Syntax
ersparen, was ich mit einem einfachen "return" in der Methode leicht erreichen könnte. Er soll aber
schreiben dürfen, um anstelle des Bezeichners "objekt" auch komplizierte Ausdrücke nur einmal schreiben zu müssen.
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 15:15
von deets
@Goswin
Siehste, mit ein bisschen Muehe und ohne verwirrendes Beiwerk versteht man die Frage auch.
Und die Antwort ist ganz einfach: nein, es gibt keine Magie, durch die man ein neues Objekt erzeugen, und alle Referenzen auf ein anderes Objekt dadurch ersetzen kann.
Ob das aber ueberhaupt eine relevante Frage ist, wage ich mal zu bezweifeln. Denn du kannst deine transform-Funktion ja schreiben, wie's dir beliebt - und einfach jedweden internen Zustand aendern, ganz nach gusto.
Viel wichtiger ist die Frage, ob die API die du deinen Benutzern da anbietest sinnvoll ist. Das Beispiel von list.sort und die spaetere Einfuehrung von sorted zeigen, dass es eigentlich oft besser ist, eine nicht-modifizierende API anzubieten, die ein neues Objekt erstellt. Dann ist es dem Nutzer ueberlassen, womit er arbeiten will. Das laesst sich natuerlich nicht 100%ig verallgemeinern, sonst waere Python ja streng funktional.
Aber ich finde es meistens deutlich besser, explizit zu entscheiden, wann ich ein veraendertes Objekt nur temporaer brauche, oder es eine bestehende Referenz ersetzen soll.
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 15:30
von jerch
@Goswin:
Du kannst Dir mit einer Wrapperklasse behelfen, die das Zielobjekt als Attribut mitschleift. Ein 'transform()' erstellt Dein neues Zielobjekt nach Deinem Gusto im Wrapperobjekt und bindet es an das Attribut. Wichtige Attribute des Zielobjektes kannst Du auf das Wrapperobjekt ummappen.
Allerdings ist das ein bisschen smelly, prinzipiell schliesse mich deets Ausführungen an.
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 15:43
von Goswin
@
deets: Ich glaube, du hast recht, wenn es nur um die Syntax geht. Ich könnte ja immer
Code: Alles auswählen
system = alg.def[2:,var.ind].tudas(par=str(3)).syst
system = system.abwandle()
mit anscheinend derselben Auswirkung schreiben.
Wenn ich ein wirklich großes Objekt habe (und das wird so sein), dann darf das aber auch in der Methode nicht kopiert werden. Vielleicht sollte ich eine Funktion schreiben, etwa
anstelle von einer Methode
Oder, wie <
jerch> gerade vorschlägt, eine Wrapperklasse (diese Technik muss ich noch lernen).
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 16:15
von deets
@Goswin
Der Vorteil einer extra Funktion vs. einer Methode will mir nicht einleuchten - im Gegenteil. Da musst du dann in externem Code Wissen ueber dein Objekt haben, oder aber du delegierst doch nur wieder. Und der Import wird auch nicht besser.
Wichtig ist eben, dass ding.abwandle() nix zurueckgibt - so wie list.sort das auch nicht tut. Denn nur dann kommt man nicht in die Gefahr zu glauben, da waere eine Kopie erstellt worden.
Aber wenn ich mal fragen darf: was ist denn 'richtig gross'?
Re: in-place-Veränderung eines Objektes
Verfasst: Donnerstag 15. Dezember 2011, 18:26
von Goswin
deets hat geschrieben:Aber wenn ich mal fragen darf: was ist denn 'richtig gross'?
@deets: Ja, du darfst fragen.
Ich suche
(unter anderem) die Smith-Normalform ganzzahliger Matrizen mit bis zu 30'000'000_Zeilen und 100'000_Spalten, das wären also 3'000'000'000'000 Einträge (die allermeisten davon freilich_0). Ob das wohl groß genug ist

? Ich benutze numpy.
Ich erwarte nun nicht, derart große Matrizen wirklich zu meistern, aber das Grundanliegen ist: je größer desto besser. Ich benutze Python zwar nur für einen Prototypen, aber auch der sollte nicht langsamer sein als unbedingt nötig...
Vielen Dank für dein Interesse!