Seite 1 von 1

Funktion mit Gedächtnis

Verfasst: Montag 1. Juni 2015, 22:25
von pixewakb
Hallo zusammen, ist es eigentlich denkbar, dass eine Funktion sich Ergebnisse merkt und so z. B. auf das Ergebnis des letzten Durchgangs zurückgreifen kann - ohne, dass ich das Ergebnis wieder als Parameter übergeben muss!? Ich dachte an globale Konstanten, die man nicht verwenden soll. Listen haben - für mich - teilweise auch ein seltsames Verhalten!? Könnte man damit einer Funktion ein Gedächtnis geben!? Ist das sinnvoll? Schaffe ich mir Probleme!?

Re: Funktion mit Gedächtnis

Verfasst: Montag 1. Juni 2015, 22:57
von BlackJack
@pixewakb: Wenn man sich etwas über Funktionsaufrufe hinweg merken will/muss, dann verwendet man üblicherweise keine Funktionen sondern eine Klasse mit einer Methode. Damit hat man dann auch keine globalen *Variablen* (was *Konstanten* damit zu tun haben sollen erschliesst sich mir nicht so ganz). Wenn es wirklich nur eine Methode neben der `__init__()` gibt, bietet sich `__call__()` dafür an.

Re: Funktion mit Gedächtnis

Verfasst: Montag 1. Juni 2015, 23:25
von snafu
Ich hatte die Frage jetzt eher so verstanden, dass etwas wie lru_cache gesucht wird.

Re: Funktion mit Gedächtnis

Verfasst: Dienstag 2. Juni 2015, 00:25
von jerch
Ein Generator wäre dafür auch denkbar.

Re: Funktion mit Gedächtnis

Verfasst: Dienstag 2. Juni 2015, 08:12
von bwbg
Das stellt sich mir die Frage, warum willst Du, dass sich eine Funktion einen inneren Zustand merkt und diesen bei weiteren Aufrufen verwendet? Gibt es ein konkretes Problem, von dem Du glaubst, es damit lösen zu können?

Ich definiere Funktionen nahezu ausschließlich referentiell transparent. Zusammengefasst: Bei gleichen Parametern gibt (bzw. sollte sie) die Funktion immer das gleiche Ergebnis zurück. Ist das nicht der Fall, dokumentiere ich dieses Verhalten explizit.

Will man das funktional lösen, könnte man den "inneren Zustand" als Parameter übergeben und könnte diesen (möglicherweise modifizierten) Zustand zusammen mit dem eigentlichen Berechnungsergebnis (als Tupel) zurück geben.

Objektorientiert ist BlackJacks Vorschlag die vorzuziehende Lösung (Python ist objektorientiert). Je nach Anwendungsfall wäre auch ein Generator angebracht (jerch). An diesem Punkt solltest Du uns verraten, was Du vorhast!

Re: Funktion mit Gedächtnis

Verfasst: Dienstag 2. Juni 2015, 10:14
von snafu
pixewakb hat geschrieben:(...) ohne, dass ich das Ergebnis wieder als Parameter übergeben muss!?
Ok, ich kann meine Theorie vom Cache wohl verwerfen. Diesen Teil hatte ich gestern anscheinend überlesen.

Aber 100%ig schlau aus dem Eingangsbeitrag werde ich immer noch nicht...

Re: Funktion mit Gedächtnis

Verfasst: Dienstag 2. Juni 2015, 21:29
von pixewakb
Hintergrund ist Zeitreihenanalyse mit exponentieller Glättung. Ich kann das anders (installierte Software) erledigen, würde es aber gerne Python erledigen lassen. Bei der exponentiellen Glättung wird das letzte Ergebnis wieder in die Formel eingesetzt, d. h. ich müsste das als Parameter wieder übergeben. Da eine Liste mit Messdaten abgearbeitet wird, dachte ich mir, dass es vielleicht eine sinnvolle Möglichkeit gibt, den "letzten" Wert irgendwie in der Funktion zu belassen. Vorteil für mich wäre das in der main-Schleife nicht irgendwelche Variablen irgendwelche Werte aufnehmen müssen. Wahrscheinlich dumme Idee!?

Re: Funktion mit Gedächtnis

Verfasst: Dienstag 2. Juni 2015, 21:39
von BlackJack
@pixewakb: Das klingt wirklich nach keiner so guten Idee. Da würde ich eine generische Funktion für schreiben die das wiederholte aufrufen mit dem letzten Wert erledigt.

Re: Funktion mit Gedächtnis

Verfasst: Dienstag 2. Juni 2015, 23:04
von snafu
pixewakb hat geschrieben:Da eine Liste mit Messdaten abgearbeitet wird, dachte ich mir, dass es vielleicht eine sinnvolle Möglichkeit gibt, den "letzten" Wert irgendwie in der Funktion zu belassen. Vorteil für mich wäre das in der main-Schleife nicht irgendwelche Variablen irgendwelche Werte aufnehmen müssen. Wahrscheinlich dumme Idee!?
Einer der Merkregeln für Python lautet: "Explicit is better than implicit".

Mit anderen Worten: Das, was dir vielleicht im ersten Moment komfortabel erscheint, bringt zuviel Magie ins Spiel. Es hätte keinen wesentlichen Nachteil, wenn du beim Aufrufer den letzten Wert der Rückgabe ermittelst und den dann halt wieder übergibst. Es zwingt dich auch niemand dazu, das direkt in `main()` zu machen. Ich würde sogar dazu raten, dies auf jeden Fall auszulagern.