Welchen Nutzen oder welche Auswirkungen könnten wir mit Python-Code wie diesem erzielen:
class some_class(parent_class):
def doOp(self, x, y):
def add(x, y):
return x + y
return add(x, y)
Ich fand dies in einem Open-Source-Projekt, das innerhalb der verschachtelten Funktion etwas Nützliches tat, aber absolut nichts außerhalb davon tat, außer es aufzurufen. (Den eigentlichen Code finden Sie hier .) Warum könnte jemand ihn so codieren? Gibt es einen Vorteil oder Nebeneffekt beim Schreiben des Codes innerhalb der verschachtelten Funktion und nicht in der äußeren, normalen Funktion?
python
nested-function
Hosam Aly
quelle
quelle
Antworten:
Normalerweise tun Sie dies, um Verschlüsse zu machen :
def make_adder(x): def add(y): return x + y return add plus5 = make_adder(5) print(plus5(12)) # prints 17
Innere Funktionen können über den umschließenden Bereich (in diesem Fall die lokale Variable
x
) auf Variablen zugreifen . Wenn Sie nicht auf Variablen aus dem umschließenden Bereich zugreifen, handelt es sich nur um normale Funktionen mit einem anderen Bereich.quelle
plus5 = functools.partial(operator.add, 5)
. Dekorateure wären ein besseres Beispiel für Verschlüsse.Abgesehen von Funktionsgeneratoren, bei denen die interne Funktionserstellung fast die Definition eines Funktionsgenerators ist, ist der Grund, warum ich verschachtelte Funktionen erstelle, die Verbesserung der Lesbarkeit. Wenn ich eine winzige Funktion habe, die nur von der äußeren Funktion aufgerufen wird, füge ich die Definition ein, damit Sie nicht herumspringen müssen, um festzustellen, was diese Funktion tut. Ich kann die innere Methode immer außerhalb der Kapselungsmethode verschieben, wenn ich die Funktion zu einem späteren Zeitpunkt wiederverwenden muss.
Spielzeugbeispiel:
import sys def Foo(): def e(s): sys.stderr.write('ERROR: ') sys.stderr.write(s) sys.stderr.write('\n') e('I regret to inform you') e('that a shameful thing has happened.') e('Thus, I must issue this desultory message') e('across numerous lines.') Foo()
quelle
Ein potenzieller Vorteil der Verwendung innerer Methoden besteht darin, dass Sie lokale Variablen der äußeren Methode verwenden können, ohne sie als Argumente zu übergeben.
def helper(feature, resultBuffer): resultBuffer.print(feature) resultBuffer.printLine() resultBuffer.flush() def save(item, resultBuffer): helper(item.description, resultBuffer) helper(item.size, resultBuffer) helper(item.type, resultBuffer)
kann wie folgt geschrieben werden, was wohl besser liest
def save(item, resultBuffer): def helper(feature): resultBuffer.print(feature) resultBuffer.printLine() resultBuffer.flush() helper(item.description) helper(item.size) helper(item.type)
quelle
Ich kann mir keinen guten Grund für solchen Code vorstellen.
Vielleicht gab es einen Grund für die innere Funktion in älteren Revisionen, wie bei anderen Ops.
Dies ist beispielsweise etwas sinnvoller:
class some_class(parent_class): def doOp(self, op, x, y): def add(x, y): return x + y def sub(x,y): return x - y return locals()[op](x,y) some_class().doOp('add', 1,2)
aber dann sollte die innere Funktion stattdessen ("private") Klassenmethoden sein:
class some_class(object): def _add(self, x, y): return x + y def doOp(self, x, y): return self._add(x,y)
quelle
Die Idee hinter lokalen Methoden ähnelt lokalen Variablen: Verschmutzen Sie nicht den größeren Namensraum. Offensichtlich sind die Vorteile begrenzt, da die meisten Sprachen solche Funktionen nicht auch direkt bereitstellen.
quelle
Sind Sie sicher, dass der Code genau so war? Der normale Grund für so etwas ist das Erstellen eines Teils - einer Funktion mit eingebauten Parametern. Das Aufrufen der äußeren Funktion gibt eine aufrufbare Funktion zurück, die keine Parameter benötigt und daher gespeichert und an einem Ort verwendet werden kann, an dem es unmöglich ist, Parameter zu übergeben. Der von Ihnen gepostete Code führt dies jedoch nicht aus. Er ruft die Funktion sofort auf und gibt das Ergebnis und nicht das aufrufbare zurück. Es kann nützlich sein, den tatsächlichen Code zu veröffentlichen, den Sie gesehen haben.
quelle