Was macht ein selbstgeschriebener Dekorateur (wie @login_required) eigentlich?

7

In meiner Flask-App habe ich eine View-Funktion wie folgt definiert:

%Vor%

Wo der Dekorator wie folgt definiert wird:

%Vor%

Ich habe im Grunde nur kopiert-eingefügt, da ich einige Quellen gefunden habe, wo dieser Code verwendet wird, aber nicht erklärt.

Es ist ziemlich einfach zu verstehen, WAS dieser Code tut: Er erlaubt mir, einen Decorator zu verwenden, der nach app.route () und vor main () für jede Anfrage aufgerufen wird, was mir erlaubt, nach einem aktiven Login zu suchen so.

Also, als Flask / Python-Neuling würde ich gerne wissen, wie das genau funktioniert, besonders:
- Was ist das Argument "etwas"? Ist das die Anfrage ?! - Was sind die Argumente und Kwargs (Schlüsselwort Argumente?)?
- Warum muss ich eine Methode INNERHALB einer Methode umbrechen, um diese als Dekorator zu verwenden?
- Ist das nur mit Flasche möglich? Gibt es andere Situationen, in denen so etwas nützlich sein könnte?

    
MrTrustworthy 05.11.2013, 19:55
quelle

3 Antworten

18

Willkommen bei Python! Das sind viele gute Fragen. Nehmen wir sie nacheinander. Auch nur ein Punkt der fairen Warnung. Bei diesem Thema dreht sich Ihr Kopf eine Weile, bevor alles zusammenklickt.

Zur Referenz: Hier ist der Beispieldekorator und die Funktion, die eingerichtet wird:

%Vor%

Was ist das Argument "etwas"? Ist das die Bitte?!

Um diese Frage zu beantworten, müssen wir zuerst antworten, was ein Dekorateur ist. Die Antwort kann je nach Art des zu dekorierenden Objekts variieren. In diesem Fall, wenn Sie eine Funktion dekorieren, können Sie sich einen Dekorator als eine Methode / Funktion vorstellen, die es einem Programmierer ermöglicht, das Verhalten der anderen Funktion zu ändern.

Damit können wir Ihre Frage beantworten. "etwas" ist die Funktion / Methode, die Sie dekorieren werden. Ja, es ist eine Funktion, die eine andere Funktion als Argument übernimmt.

Lassen Sie uns die Sprache Ihrer Decorator-Funktion ändern, um dies deutlicher zu machen:

%Vor%

Was sind die Argumente und Kwargs?

Die kurze Antwort ist, dass dies Pythons Art ist, den Parametern zu erlauben, dass Programmierer Funktionen / Methoden schreiben, die eine variable Anzahl von Schlüsselwörtern & amp; Nicht-Schlüsselwort-Argumente.

Normalerweise geben Sie beim Schreiben einer Funktion die Parameter explizit an. Zum Beispiel:

%Vor%

Das ist jedoch nicht der einzige Weg, Dinge zu tun. Sie können auch die * Argumente oder ** Kargs verwenden, um dasselbe zu erreichen:

%Vor%

Wie es sich auf Ihre Frage bezieht, werden *args/**kwargs häufig in Decorators verwendet, da Decorators oft auf eine Vielzahl von Methoden angewendet werden, die eine Vielzahl von Parametern benötigen.

Die Verwendung von args/**kwargs ermöglicht Ihrer Decorator-Methode, die Methode, die ursprünglich für die Methode erforderlich war, über die Decorator-Funktion zu übergeben. Wenn das Ihren Kopf dreht, lassen Sie es mich wissen und ich werde es klären .

Lassen Sie uns main () ändern, damit das klarer ist:

%Vor%

Warum muss ich eine Methode INNERHALB einer Methode umbrechen, um diese als Dekorator zu verwenden?

Dies ist meiner Meinung nach der komplizierteste Teil des Verständnisses für Dekorateure. Der Schlüssel besteht darin zu verstehen, dass ein Decorator im Kern den Namen der ursprünglichen Funktion übernimmt.

Der einfachste Weg, dies zu verstehen, ist, den Decorator ohne die praktische @ -Syntax anzuwenden. Folgendes ist äquivalent:

%Vor%

Halten Sie an Ihren Pferden fest, das ist, wo es GEIL wird! Was beide dieser Code-Fragmente Python sagen, ist, "das Wort 'main' sollte sich nicht mehr auf die main () Funktion beziehen , aber zu den Ergebnissen login_required () -Funktion, wenn es die ursprüngliche main () -Funktion als Parameter übergeben wurde.

WAT!?

Ja. Ein Aufruf von main () bezieht sich nun auf die Ergebnisse des Aufrufs von login_required (main ()). Dies ist auch der Grund, warum login_required die geschachtelte Funktion zurückgibt. Die neue main () muss immer noch eine Funktion sein, genau wie die alte.

Der Unterschied besteht darin, dass die neue main-Funktion nun eine Instanz von wrap () ist, die durch den an login_required () übergebenen Parameter angepasst wird.

Also ... effektiv ist main () nun gleich dem folgenden:

%Vor%

Ist das nur mit Flask möglich? Gibt es andere Situationen, in denen so etwas nützlich sein könnte?

Definitiv nicht! Decorators sind eine der vielen tollen Funktionen, die direkt in Python integriert sind. Decorators sind in jeder Situation nützlich, in der Sie (relativ kleine meiner Meinung nach) Änderungen an bestehenden Funktionen / Methoden vornehmen möchten, wenn Sie keine zusätzlichen Funktionen erstellen möchten, um eine Code-Duplizierung zu vermeiden.

    
eikonomega 05.11.2013, 21:39
quelle
1

Einführung in Dekorateure: Sie können es lesen hier .

  

Was sind die Argumente und Kwargs (Schlüsselwortargumente?)?

args , wenn Sie nicht sicher sind, wie viele Argumente an Ihre Funktion übergeben werden können.

%Vor%

kwargs : benannte Argumente. Grundsätzlich wie oben, es ist wie Sie ein Wörterbuch übergeben.

%Vor%
  

Warum muss ich eine Methode INNERHALB einer Methode umbrechen, um diese als Dekorator zu verwenden?

Überprüfen Sie den Link Dekorateur Link.

  

Ist das nur mit Flasche möglich? Gibt es noch andere Situationen?   wie könnte das praktisch sein?

Nein, Dekoratoren sind in Python generell verfügbar, sie sind nicht nur auf flask beschränkt. Sie können es für Protokollierung, Synchronisation und viele andere Zwecke verwenden. In Django können Sie eine Post- oder Get-Anfrage mit einem Decorator oder für login_required usw. erlauben ...

    
moenad 05.11.2013 20:18
quelle
0

Dies:

%Vor%

Ist gleich:

%Vor%

Die Definition für login_required verwendet die alte main als something , umschließt eine neue Funktion und gibt diese zurück.

    
Lynn 05.11.2013 20:10
quelle

Tags und Links