Stellen Sie sich vor, ich hätte ein Python-Modul mit einer Funktion:
%Vor%Aber manchmal möchte ich Ergebnisse einiger Zwischenberechnungen erhalten (zum Beispiel könnte ich eine Funktion haben, die eine Matrix umkehrt und die Determinante kennen möchte, die auch als Zwischenschritt berechnet wurde). Offensichtlich möchte ich diese Berechnungen nicht noch einmal wiederholen, wenn sie bereits innerhalb dieser Funktion ausgeführt wurden.
Meine erste Idee ist, ein Diktat zurückzugeben:
%Vor% Aber ich erinnere mich an keine Funktionen in numpy oder scipy, die dicts zurückgeben und so scheint es, dass dies keine gute Idee ist. (Warum?) Auch routinemäßig muss ich immer sumvars(x,y,z)['final']
für einen Standard-Rückgabewert eingeben ...
Eine andere Option, die ich sehe, ist das Erstellen globaler Variablen, aber es scheint falsch zu sein, eine Menge davon in meinem Modul zu haben. Ich müsste mich an ihre Namen erinnern und außerdem nicht an die Funktion selbst gebunden sein, sieht wie eine schlechte Designwahl aus.
Was wäre der richtige Funktionsentwurf für eine solche Situation?
Im Allgemeinen, wenn Sie zwei verschiedene Möglichkeiten haben, Daten zurückzugeben, gehen Sie voran und machen Sie zwei verschiedene Funktionen. "Flach ist besser als verschachtelt". Rufen Sie einfach den anderen an, damit Sie sich nicht wiederholen.
Zum Beispiel hat urllib.parse
in der Standardbibliothek parse_qs
(was eine dict
zurückgibt) und parse_qsl
(die eine list
zurückgibt). parse_qs
ruft gerade den anderen auf:
Ziemlich einfach. In deinem Beispiel scheint es also gut zu sein,
zu haben %Vor% (Ich bevorzuge die Rückgabe von namedtuple
s anstelle von dict
s von meinen APIs, es ist einfach hübscher)
Ein weiteres offensichtliches Beispiel ist in re
: re.findall
ist eine eigene Funktion, nicht ein Konfigurations-Flag für search
.
Nun, die Standard-Bibliothek ist eine weitläufige Sache, die von vielen Autoren gemacht wurde, so dass Sie zu jedem Beispiel Gegenbeispiele finden. Sie werden viel öfter das obige Muster sehen als eine Omnibus-Funktion, die einige Konfigurationsflags akzeptiert, und ich finde sie viel besser lesbar.
Setzen Sie die allgemeine Berechnung in eine eigene Funktion, wie Jayanth Koushik empfohlen hat, wenn diese Berechnung entsprechend benannt werden kann. Wenn Sie viele Werte (ein Zwischenergebnis und ein Endergebnis) aus einer einzelnen Funktion zurückgeben möchten, kann ein dict je nach Ziel ein Overkill sein, aber in Python ist es viel natürlicher, einfach ein Tupel zurückzugeben, wenn Ihre Funktion es hat viele zurückzugebende Werte:
%Vor%Nicht sicher, ob Funktionsattribute eine gute Idee sind:
%Vor%Hinweis: wie @BrenBarn erwähnt, diese Idee ist genau wie globale Variablen , Ihre zuvor berechneten "Zwischenergebnisse" konnten nicht gespeichert werden, wenn Sie sie wiederverwenden möchten.
Ich glaube, die richtige Lösung besteht darin, eine Klasse zu verwenden, um besser zu verstehen, was Sie modellieren. Im Fall der Matrix könnten Sie beispielsweise die Determinante einfach im Attribut "determinant" speichern.
Hier ist ein Beispiel mit Ihrem Matrixbeispiel.
%Vor%Damit können Sie Ihre Methode auch in einfachere Methoden aufteilen, zum Beispiel für die Berechnung der Determinante Ihrer Matrix.
Eine andere Variante:
%Vor%Die Funktion gibt immer den gewünschten Wert zurück, ohne sie in ein Tupel oder Wörterbuch zu packen. Die Zwischenergebnisse sind weiterhin verfügbar, jedoch nur auf Anfrage. Der Anruf
%Vor% gibt nur 6
zurück, ohne Zwischenwerte zu speichern. Aber der Anruf
gibt die gleiche Antwort zurück 6
und fügt die Zwischenberechnungen in das angegebene Wörterbuch ein.