1. Anonyme Funktion
Anonyme Funktion bezieht sich auf eine Funktion, die an keinen Bezeichner gebunden ist. Sie wird hauptsächlich im Bereich funktionaler Programmiersprachen verwendet:
1) Wird als Parameter übergeben Funktionen höherer Ordnung (Funktion höherer Ordnung), wie die in Python integrierten Funktionen Filter/Map/Reduce, sind alle typische Funktionen höherer Ordnung
2) als Rückgabewert der Funktion höherer Ordnung (obwohl die „Wert“ ist hier eigentlich Es handelt sich um ein Funktionsobjekt)
Im Vergleich zu benannten Funktionen sind anonyme Funktionen syntaktisch leichter, wenn die Funktion nur einmal oder eine begrenzte Anzahl von Malen aufgerufen wird.
In Bezug auf die spezifische Syntax unterstützt Python anonyme Funktionen, deren Funktionskörper ein Ausdruck durch Lambda-Syntax ist, das heißt: Der Lambda-Ausdruck von Python ist im Wesentlichen eine anonyme Funktion, aber sein Funktionskörper kann nur ein Ausdruck sein und keine anderen Anweisungen enthalten.
Darüber hinaus verwenden dynamische Sprachen auf hoher Ebene häufig anonyme Funktionen, um erweiterte Syntax wie Schließungen oder Dekoratoren zu implementieren.
In einigen Fällen lässt die Verwendung von Lambda-Ausdrücken Python-Programme sehr prägnant aussehen. Das Folgende ist beispielsweise ein Codebeispiel zum Sortieren von Diktatelementen nach Wert:
>>> foo = {'father' : 65, 'mother' : 62, 'sister' : 38, 'brother' : 29, 'me' : 28} >>> sorted(foo.iteritems(), key=lambda x: x[1]) [('me', 28), ('brother', 29), ('sister', 38), ('mother', 62), ('father', 65)]
2. Ein Abschluss
Ein Abschluss ist im Wesentlichen eine Referenzumgebung, die ihre Funktionen oder Funktionsreferenzen enthält, die „Referenz“. „Umgebung“ wird hier normalerweise durch eine Tabelle verwaltet, die Verweise auf nicht-lokale Variablen speichert, auf die der Funktionskörper zugreift.
Im Vergleich zu Funktionszeigern in der C-Sprache ermöglichen Abschlüsse verschachtelten Funktionen den Zugriff auf nicht-lokale Variablen außerhalb ihres Gültigkeitsbereichs, was mit den Gültigkeitsbereichssuchregeln des Python-Interpreters für Variablen zusammenhängt (Python unterstützt die Suchregeln von LEGB). Wenn Sie mehr erfahren möchten , können Sie sich auf die ausführliche Erläuterung des Bereichs und der Suchregeln in Kapitel 17 der 4. Ausgabe von „Learning Python“ beziehen oder diesen Artikel für ein schnelles Verständnis lesen.
Für Sprachen, deren Laufzeitspeicherzuweisungsmodell lokale Variablen auf einem linearen Stapel erstellt (normalerweise wie die C-Sprache), ist es normalerweise schwierig, Abschlüsse zu unterstützen. Denn wenn die Funktion in der zugrunde liegenden Implementierung dieser Sprachen zurückkehrt, werden die in der Funktion definierten lokalen Variablen zerstört, wenn der Funktionsstapel recycelt wird. Die zugrunde liegende Implementierung von Abschlüssen erfordert jedoch, dass die nicht lokalen Variablen, auf die sie zugreifen möchten, gültig bleiben, wenn der Abschluss ausgeführt wird, bis der Lebenszyklus des Abschlusses endet. Dies bedeutet, dass auf diese nicht lokalen Variablen nur dann zugegriffen werden kann, wenn sie bestimmt sind Auf sie kann nur dann zugegriffen werden, wenn sie verwendet werden, nicht jedoch, wenn die Funktion, die diese Variablen definiert, zurückkehrt. Daher verwenden Sprachen, die Schließungen auf natürliche Weise unterstützen, normalerweise die Speicherbereinigung, um den Speicher zu verwalten, da der GC-Mechanismus sicherstellt, dass Variablen vom System zerstört werden und ihr Speicherplatz nur dann zurückgefordert wird, wenn nicht mehr darauf verwiesen wird.
In Bezug auf die spezifische Syntax werden Abschlüsse normalerweise von verschachtelten Funktionsdefinitionen begleitet. Am Beispiel von Python sieht ein einfaches Abschlussbeispiel wie folgt aus:
#!/bin/env python #-*- encoding: utf-8 -*- def startAt_v1(x): def incrementBy(y): return x + y print 'id(incrementBy)=%s' % (id(incrementBy)) return incrementBy def startAt_v2(x): return lambda y: x + y if '__main__' == __name__: c1 = startAt_v1(2) print 'type(c1)=%s, c1(3)=%s' % (type(c1), c1(3)) print 'id(c1)=%s' % (id(c1)) c2 = startAt_v2(2) print 'type(c2)=%s, c2(3)=%s' % (type(c2), c2(3))
Das Ausführungsergebnis lautet wie folgt:
id(incrementBy)=139730510519782 type(c1)=<type 'function'>, c1(3)=5 id(c1)=139730510519782 type(c2)=<type 'function'>, c2(3)=5
Im obigen Beispiel implementieren startAt_v1 und startAt_v2 beide Abschlüsse , wobei: v1 mithilfe verschachtelter Definitionsfunktionen implementiert wird; v2 mithilfe von Lambda-Ausdrücken/anonymen Funktionen implementiert wird.
Wir nehmen v1 als Beispiel, um den Abschluss zu veranschaulichen:
1) Die Funktion startAt_v1 akzeptiert 1 Parameter und gibt ein Funktionsobjekt zurück, und das Verhalten dieses Funktionsobjekts wird durch die verschachtelte definierte Funktion incrementBy implementiert.
2) Für die Funktion incrementBy ist die Variable x eine sogenannte nicht-lokale Variable (da x weder eine durch die Funktion definierte lokale Variable noch eine globale Variable im üblichen Sinne ist, implementiert incrementBy ein bestimmtes Funktionsverhalten). kehrt zurück.
3) Der von c1 am Haupteingang empfangene Rückgabewert ist ein Funktionsobjekt. Aus id(incrementBy) == id(c1) kann geschlossen werden, dass das Objekt, auf das c1 zeigt, und das Objekt „zeigt“. to“ mit dem Funktionsnamen incrementBy sind eigentlich dasselbe Funktionsobjekt.
4) Da das Objekt, auf das c1 zeigt, im Vergleich zu Objekten gewöhnlicher Funktionen von Pythons Unterstützung für Abschlüsse profitiert, kann es auf nicht-lokale Variablen zugreifen, die nicht im Rahmen seiner Funktion liegen, und diese Variable ist die äußere Wrapper-Funktion von incrementBy wird durch die Eingabeparameter von startAt_v1 bereitgestellt. Daher verfügt das Funktionsobjekt, auf das c1 zeigt, über eine „Speicher“-Funktion für die Eingabeparameter seiner äußeren Wrapping-Funktion. Beim Erstellen eines Abschlusses durch Aufrufen der äußeren Wrapping-Funktion werden unterschiedliche Eingabeparameter verwendet durch die innere Funktion als Referenzumgebung gepflegt.
5) Beim Aufruf von c1(3) werden die eingehenden Parameter zusammen mit den Parametern der äußeren Verpackungsfunktion berechnet, die sich auf die Umgebungswartung beziehen, um das Endergebnis zu erhalten.
Die obige Schrittanalyse veranschaulicht das Grundprinzip eines Abschlusses von der Erstellung bis zur Ausführung. Nachdem Sie diesen Fall verstanden haben, sollte auch das Konzept des Abschlusses klar sein.
3. Decorator
Python unterstützt die Decorator-Syntax. Das Konzept der Dekoratoren ist für Anfänger relativ unklar, da es mehrere Konzepte der funktionalen Programmierung umfasst (z. B. anonyme Funktionen und Abschlüsse). Aus diesem Grund werden in diesem Artikel zunächst anonyme Funktionen und Abschlüsse vorgestellt.
我们引用这篇文章对装饰器的定义:
A decorator is a function that takes a function object as an argument, and returns a function object as a return value.
从这个定义可知,装饰器本质上只是一个函数,它借助闭包的语法去修改一个函数(又称被装饰函数)的行为,即decorator其实是个闭包函数,该函数以被装饰函数名(这个函数名其实是一个函数对象的引用)作为入参,在闭包内修改被装饰函数的行为后,返回一个新的函数对象。
特别说明:decorator并非必须以函数形式出现,它可以是任何可被调用的对象,例如它也可以class形式出现,参见这篇文章给出的例子。
在定义好函数装饰器的前提下,当外部调用这个被装饰函数时,decorator的语法糖会由Python解释器解释为先执行装饰器函数,然后在装饰器返回的新函数对象上继续执行其余语句。
来个实例分析一下:
#!/bin/env python #-*- encoding: utf-8 -*- def wrapper(fn): def inner(n, m): n += 1 print 'in inner: fn=%s, n=%s, m=%s' % (fn.__name__, n, m) return fn(n, m) + 6 // 这里有return且返回值为int对象 return inner @wrapper def foo(n, m): print 'in foo: n=%s, m=%s' % (n, m) return n * m print foo(2, 3)
上面的示例中,foo通过@wrapper语法糖声明它的装饰器是wrapper,在wrapper中,定义了嵌套的inner函数(该函数的参数列表必须与被装饰函数foo的参数列表保持一致),装饰器wrapper修改foo的行为后,返回inner(注意:由于inner的返回值是个int对象,故wrpper最终返回的也是个int对象)。
调用foo(2, 3)时,Python解释器先调用wrapper对foo做行为改写,然后返回int对象,不难推测,上述代码的执行结果如下:
in inner: fn=foo, n=3, m=3 in foo: n=3, m=3 foo(2, 3)=15
更多Python的几个高级语法概念浅析(lambda表达式闭包装饰器)相关文章请关注PHP中文网!