myxin hat geschrieben:ahhh - heisst, f_5 ist jetzt eine Funktion vom Typ addr, oder?
Jein. f_5 ist eine Funktion. Eine Funktion vom Typ "Funktion", weil in Python haben Funktionen nun mal so einen Typ. Es ist an sich die Funktion ``adder`` die den Namen ``m`` als Parameter hat und den Namen ``n`` aus dem Namensraum der Funktion nimmt in der sie definiert wurde (``add_n``).
Da mag auf den ersten Blick ein relativ sinnloses Feature zu sein, aber es gibt einen Programmierstil wo sowas häufig zur Anwendung kommt. Mal ein Beispiel, du willst eine Liste sortieren:
Code: Alles auswählen
collection = [(2, 3), (4, 2), (4, 1), (5, 5)]
sorted(collection)
# [(2, 3), (4, 1), (4, 2), (5, 5)]
Nun willst du aber nicht nach dem ersten Element der Liste sortieren sondern nach dem Zeiten. Die eingebaute Funktion ``sorted`` nimmt einen Parameter namens Key entgegen, der eine Funktion entgegennimmt. Diese Funktion wird auf jedes Element angewendet um die Sortierreihenfolge anzugeben. In unserem Fall wäre das das einfach das zweite Element des Tupels. Also bauen wir so eine Funktion:
Code: Alles auswählen
def second(item):
return item[1]
sorted(collection, key=second)
# [(4, 1), (4, 2), (2, 3), (5, 5)]
Gut, das ist jetzt aber doof, wenn wir das ändern wollen und etwa nach einem dritten Element sortieren wollen müssten wir ja eine Funktion schreiben, die ``third`` heißt. Und für das vierte Element noch eine, etc. etc. Wie wärs wenn wir statt die Funktion immer hinzuschreiben, sie quasi programmatisch erzeugen? Da kommen verschachtelte Funktionen ins Spiel:
Code: Alles auswählen
def get_nth_item(num):
def inner(item):
return item[num]
return inner
So, jetzt haben wir quasi eine Funktionsfabrik, die uns Funktionen ausgibt, die wir an den ``key``-Parameter von ``sorted`` geben können. Probieren wir das mal aus:
Code: Alles auswählen
sorted(collection, key=get_nth_item(1))
# [(4, 1), (4, 2), (2, 3), (5, 5)]
Oha, das funktioniert ja fein! Damit haben wir unseren Code mittels geschachtelter Funktionen erfolgreich vereinfacht. Prima! Das wäre dann das Ende des Beispiels.
Die nächste Vereinfachung wäre übrigens festzustellen dass es so eine Funktion in der Stdlib bereits gibt:
Code: Alles auswählen
from operator import itemgetter
sorted(collection, key=itemgetter(1))
# [(4, 1), (4, 2), (2, 3), (5, 5)]
Du siehst, ``itemgetter(1)`` gibt dir auch eine verschachtelte Funktion zurück.