Einfaches Beispiel. Zwei Methoden, eine von einer anderen aufgerufen:
def method_a(arg):
some_data = method_b(arg)
def method_b(arg):
return some_data
In Python können wir def
in einem anderen deklarieren def
. Also, wenn method_b
es für nur erforderlich ist und von dort angerufen wird method_a
, sollte ich es method_b
innen deklarieren method_a
? so was :
def method_a(arg):
def method_b(arg):
return some_data
some_data = method_b(arg)
Oder sollte ich das vermeiden?
python
coding-style
nukl
quelle
quelle
method_b
? (@inspector: Das müssen Sie genau genommen, aber es ist immens nützlich, wenn Sie sich mit funktionaler Programmierung beschäftigen, insbesondere mit Schließungen).Antworten:
Ist es das, wonach du gesucht hast? Es heißt eine Schließung .
quelle
do_it()
tut, vermutlich etwas komplizierter als das, was von einer Arithmetik in einer einzigenreturn
Anweisung gehandhabt werden kann .Auf diese Weise gewinnen Sie nicht wirklich viel. Tatsächlich wird es langsamer
method_a
, da die andere Funktion bei jedem Aufruf definiert und neu kompiliert wird. Angesichts dessen wäre es wahrscheinlich besser, dem Funktionsnamen nur einen Unterstrich voranzustellen, um anzuzeigen, dass es sich um eine private Methode handelt - d_method_b
. H.Ich nehme an, Sie möchten dies möglicherweise tun, wenn die Definition der verschachtelten Funktion aus irgendeinem Grund jedes Mal geändert wird. Dies kann jedoch auf einen Fehler in Ihrem Design hinweisen. Es gibt jedoch einen triftigen Grund, dies zu tun, damit die verschachtelte Funktion Argumente verwenden kann, die an die äußere Funktion übergeben, aber nicht explizit an sie weitergegeben wurden. Dies tritt beispielsweise manchmal beim Schreiben von Funktionsdekoratoren auf. Es ist das, was in der akzeptierten Antwort gezeigt wird, obwohl ein Dekorateur nicht definiert oder verwendet wird.
Aktualisieren:
Hier ist der Beweis, dass das Verschachteln langsamer ist (mit Python 3.6.1), obwohl dies in diesem trivialen Fall zugegebenermaßen nicht viel ist:
Hinweis: Ich
self
habe Ihren Beispielfunktionen einige Argumente hinzugefügt , um sie eher wie echte Methoden zu gestalten (obwohlmethod_b2
dies technisch immer noch keine Methode derTest
Klasse ist). Auch die verschachtelte Funktion wird in dieser Version im Gegensatz zu Ihrer tatsächlich aufgerufen.quelle
method_b = self._method_b
und dann aufrufenmethod_b
, um die wiederholte Suche nach Attributen zu vermeiden. (Es kommt vor, dass ich in letzter Zeit eineEine Funktion innerhalb einer Funktion wird üblicherweise für Verschlüsse verwendet .
(Es gibt eine Menge Streit über was genau macht einen Verschluss einen Verschluss .)
Hier ist ein Beispiel mit dem eingebauten
sum()
. Es definiertstart
einmal und verwendet es von da an:In Benutzung:
Eingebauter Python-Verschluss
functools.partial
ist ein Beispiel für eine Schließung.In den Python-Dokumenten entspricht dies in etwa:
(Ein großes Lob an @ user225312 unten für die Antwort. Ich finde dieses Beispiel einfacher herauszufinden und werde hoffentlich helfen, den Kommentar von @ mango zu beantworten.)
quelle
Nein, definieren Sie im Allgemeinen keine Funktionen innerhalb von Funktionen.
Es sei denn, Sie haben einen wirklich guten Grund. Was du nicht tust.
Warum nicht?
lambda
Ausdruck verwenden .Was ist ein wirklich guter Grund, Funktionen innerhalb von Funktionen zu definieren?
Wenn Sie tatsächlich einen Dingdang- Verschluss wollen .
quelle
Es ist eigentlich in Ordnung, eine Funktion in einer anderen zu deklarieren. Dies ist besonders nützlich, um Dekorateure zu erstellen.
Als Faustregel gilt jedoch, dass es bei einer komplexen Funktion (mehr als 10 Zeilen) möglicherweise besser ist, sie auf Modulebene zu deklarieren.
quelle
Ich habe diese Frage gefunden, weil ich eine Frage stellen wollte, warum es Auswirkungen auf die Leistung gibt, wenn verschachtelte Funktionen verwendet werden. Ich habe Tests für die folgenden Funktionen mit Python 3.2.5 auf einem Windows-Notebook mit einem Quad Core 2,5-GHz-Intel i5-2530M-Prozessor durchgeführt
Ich habe die folgenden 20 Male gemessen, auch für Quadrat1, Quadrat2 und Quadrat5:
und bekam die folgenden Ergebnisse
square0
hat keine verschachtelte Funktion,square1
hat eine verschachtelte Funktion,square2
hat zwei verschachtelte Funktionen undsquare5
hat fünf verschachtelte Funktionen. Die verschachtelten Funktionen werden nur deklariert, aber nicht aufgerufen.Wenn Sie also 5 verschachtelte Funktionen in einer Funktion definiert haben, die Sie nicht aufrufen, beträgt die Ausführungszeit der Funktion das Doppelte der Funktion ohne verschachtelte Funktion. Ich denke, sollte vorsichtig sein, wenn verschachtelte Funktionen verwendet werden.
Die Python-Datei für den gesamten Test, der diese Ausgabe generiert, befindet sich unter ideone .
quelle
Es ist nur ein Prinzip über Expositions-APIs.
Bei Verwendung von Python ist es eine gute Idee, die Expositions-API im Weltraum (Modul oder Klasse) zu vermeiden. Die Funktion ist ein guter Kapselungsort.
Es könnte eine gute Idee sein. wenn Sie sicherstellen
Auch wenn Missbrauch dieser Technik Probleme verursachen kann und einen Konstruktionsfehler impliziert.
Nur aus meiner Erfahrung, Vielleicht missverstehen Sie Ihre Frage.
quelle
Am Ende geht es also hauptsächlich darum, wie intelligent die Python-Implementierung ist oder nicht, insbesondere wenn die innere Funktion kein Abschluss ist, sondern lediglich ein Helfer, der nur für die Funktion benötigt wird.
In einem sauberen, verständlichen Design ist es ein gutes Design, Funktionen nur dort zu haben, wo sie benötigt werden und nicht an anderer Stelle verfügbar gemacht werden, unabhängig davon, ob sie in ein Modul, eine Klasse als Methode oder in eine andere Funktion oder Methode eingebettet sind. Wenn sie gut gemacht sind, verbessern sie wirklich die Klarheit des Codes.
Und wenn die innere Funktion ein Verschluss ist, der auch bei der Klarheit einiges helfen kann, selbst wenn diese Funktion nicht aus der enthaltenen Funktion zur anderweitigen Verwendung zurückgegeben wird.
Daher würde ich sagen, dass Sie sie im Allgemeinen verwenden, sich jedoch des möglichen Leistungseinbruchs bewusst sind, wenn Sie tatsächlich über die Leistung besorgt sind, und sie nur entfernen, wenn Sie eine tatsächliche Profilerstellung durchführen, die zeigt, dass sie am besten entfernt werden können.
Führen Sie keine vorzeitige Optimierung durch, indem Sie nur "innere Funktionen BAD" für den gesamten von Ihnen geschriebenen Python-Code verwenden. Bitte.
quelle
Es ist vollkommen in Ordnung, dies so zu tun, aber es sei denn, Sie müssen einen Abschluss verwenden oder die Funktion zurückgeben, die ich wahrscheinlich in die Modulebene eingefügt habe. Ich stelle mir im zweiten Codebeispiel vor, Sie meinen:
Andernfalls ist some_data die Funktion.
Wenn Sie es auf Modulebene haben, können andere Funktionen method_b () verwenden. Wenn Sie etwas wie Sphinx (und Autodoc) für die Dokumentation verwenden, können Sie auch method_b dokumentieren.
Möglicherweise möchten Sie auch die Funktionalität in zwei Methoden in einer Klasse einfügen, wenn Sie etwas tun, das von einem Objekt dargestellt werden kann. Dies enthält auch Logik, wenn das alles ist, wonach Sie suchen.
quelle
Mach so etwas wie:
Wenn Sie ausführen
some_function()
würden, würde es ausgeführtsome_other_function()
und 42 zurückgeben.EDIT: Ich habe ursprünglich gesagt, dass Sie eine Funktion nicht innerhalb einer anderen definieren sollten, aber es wurde darauf hingewiesen, dass es manchmal praktisch ist, dies zu tun.
quelle
Sie können es verwenden, um die Definition globaler Variablen zu vermeiden. Dies gibt Ihnen eine Alternative für andere Designs. 3 Entwürfe, die eine Lösung für ein Problem darstellen.
A) Verwenden von Funktionen ohne Globale
B) Verwenden von Funktionen mit Globalen
C) Verwenden von Funktionen innerhalb einer anderen Funktion
Lösung C) ermöglicht die Verwendung von Variablen im Bereich der äußeren Funktion, ohne dass diese in der inneren Funktion deklariert werden müssen. Könnte in einigen Situationen nützlich sein.
quelle
Funktion In Funktion Python
quelle