Dekorateure sind ein sehr leistungsfähiges und nützliches Werkzeug in Python, da es Programmierern ermöglicht, das Verhalten einer Funktion oder Klasse zu ändern. Mit Dekoratoren können wir eine andere Funktion umschließen, um das Verhalten der umschlossenen Funktion zu erweitern, ohne sie dauerhaft zu ändern. Aber bevor wir uns eingehend mit Dekorateuren befassen, wollen wir uns mit einigen Konzepten befassen, die beim Erlernen der Dekorateure nützlich sein werden.
Erstklassige Objekte
In Python sind Funktionen erstklassige Objekte Das bedeutet, dass Funktionen in Python als Argumente verwendet oder übergeben werden können.
Eigenschaften erstklassiger Funktionen:
- Eine Funktion ist eine Instanz des Objekttyps.
- Sie können die Funktion in einer Variablen speichern.
- Sie können die Funktion als Parameter an eine andere Funktion übergeben.
- Sie können die Funktion von einer Funktion zurückgeben.
- Sie können sie in Datenstrukturen wie Hash-Tabellen, Listen usw. speichern.
Betrachten Sie zum besseren Verständnis die folgenden Beispiele.
Beispiel 1: Behandeln der Funktionen als Objekte.
Python3
# Python program to illustrate functions> # can be treated as objects> def> shout(text):> >return> text.upper()> print>(shout(>'Hello'>))> yell>=> shout> print>(yell(>'Hello'>))> |
>
>
Ausgabe:
HELLO HELLO>
Im obigen Beispiel haben wir einer Variablen die Funktion Shout zugewiesen. Dadurch wird die Funktion nicht aufgerufen, sondern das Funktionsobjekt, auf das durch einen Shout verwiesen wird, wird verwendet und ein zweiter Name wird erstellt, der darauf verweist, Yell.
Beispiel 2: Übergabe der Funktion als Argument
Python3
# Python program to illustrate functions> # can be passed as arguments to other functions> def> shout(text):> >return> text.upper()> def> whisper(text):> >return> text.lower()> def> greet(func):> ># storing the function in a variable> >greeting>=> func(>'''Hi, I am created by a function passed as an argument.'''>)> >print> (greeting)> greet(shout)> greet(whisper)> |
>
>
Ausgabe:
HI, I AM CREATED BY A FUNCTION PASSED AS AN ARGUMENT. hi, i am created by a function passed as an argument.>
Im obigen Beispiel übernimmt die Begrüßungsfunktion eine andere Funktion als Parameter (in diesem Fall Shout und Whisper). Die als Argument übergebene Funktion wird dann innerhalb der Funktion Greet aufgerufen.
Beispiel 3: Rückgabe von Funktionen aus einer anderen Funktion.
Python3
Array-C-String
# Python program to illustrate functions> # Functions can return another function> def> create_adder(x):> >def> adder(y):> >return> x>+>y> >return> adder> add_15>=> create_adder(>15>)> print>(add_15(>10>))> |
>
>
Ausgabe:
25>
Im obigen Beispiel haben wir eine Funktion innerhalb einer anderen Funktion erstellt und dann die darin erstellte Funktion zurückgegeben.
Die obigen drei Beispiele veranschaulichen die wichtigen Konzepte, die zum Verständnis von Dekorateuren erforderlich sind. Nachdem wir sie durchgegangen sind, wollen wir uns nun intensiver mit Dekorateuren befassen.
Dekorateure
Wie oben erwähnt, werden Dekoratoren verwendet, um das Verhalten einer Funktion oder Klasse zu ändern. In Decorators werden Funktionen als Argument in eine andere Funktion übernommen und dann innerhalb der Wrapper-Funktion aufgerufen.
Syntax für Decorator:
@gfg_decorator def hello_decorator(): print('Gfg') '''Above code is equivalent to - def hello_decorator(): print('Gfg') hello_decorator = gfg_decorator(hello_decorator)'''> Im obigen Code ist gfg_decorator eine aufrufbare Funktion, die Code über einer anderen aufrufbaren Funktion, der hello_decorator-Funktion, hinzufügt und die Wrapper-Funktion zurückgibt.
Der Dekorateur kann das ändern Verhalten :
Python3
# defining a decorator> def> hello_decorator(func):> ># inner1 is a Wrapper function in> ># which the argument is called> > ># inner function can access the outer local> ># functions like in this case 'func'> >def> inner1():> >print>(>'Hello, this is before function execution'>)> ># calling the actual function now> ># inside the wrapper function.> >func()> >print>(>'This is after function execution'>)> > >return> inner1> # defining a function, to be called inside wrapper> def> function_to_be_used():> >print>(>'This is inside the function !!'>)> # passing 'function_to_be_used' inside the> # decorator to control its behaviour> function_to_be_used>=> hello_decorator(function_to_be_used)> # calling the function> function_to_be_used()> |
>
>
Ausgabe:
Hello, this is before function execution This is inside the function !! This is after function execution>
Sehen wir uns das Verhalten des obigen Codes an und wie er Schritt für Schritt ausgeführt wird, wenn function_to_be_used aufgerufen wird.

Kommen wir zu einem anderen Beispiel, bei dem wir es leicht herausfinden können die Ausführungszeit einer Funktion mit einem Dekorateur.
Python3
# importing libraries> import> time> import> math> # decorator to calculate duration> # taken by any function.> def> calculate_time(func):> > ># added arguments inside the inner1,> ># if function takes any arguments,> ># can be added like this.> >def> inner1(>*>args,>*>*>kwargs):> ># storing time before function execution> >begin>=> time.time()> > >func(>*>args,>*>*>kwargs)> ># storing time after function execution> >end>=> time.time()> >print>(>'Total time taken in : '>, func.__name__, end>-> begin)> >return> inner1> # this can be added to any function present,> # in this case to calculate a factorial> @calculate_time> def> factorial(num):> ># sleep 2 seconds because it takes very less time> ># so that you can see the actual difference> >time.sleep(>2>)> >print>(math.factorial(num))> # calling the function.> factorial(>10>)> |
>
>
Ausgabe:
3628800 Total time taken in : factorial 2.0061802864074707>
Was passiert, wenn eine Funktion etwas zurückgibt oder ein Argument an die Funktion übergeben wird?
In allen oben genannten Beispielen haben die Funktionen nichts zurückgegeben, es gab also kein Problem, aber möglicherweise wird der zurückgegebene Wert benötigt.
Python3
def> hello_decorator(func):> >def> inner1(>*>args,>*>*>kwargs):> > >print>(>'before Execution'>)> > ># getting the returned value> >returned_value>=> func(>*>args,>*>*>kwargs)> >print>(>'after Execution'>)> > ># returning the value to the original frame> >return> returned_value> > >return> inner1> # adding decorator to the function> @hello_decorator> def> sum_two_numbers(a, b):> >print>(>'Inside the function'>)> >return> a>+> b> a, b>=> 1>,>2> # getting the value through return of the function> print>(>'Sum ='>, sum_two_numbers(a, b))> |
>
>
Haufensortierung
Ausgabe:
before Execution Inside the function after Execution Sum = 3>
Im obigen Beispiel bemerken Sie möglicherweise einen deutlichen Unterschied in den Parametern der inneren Funktion. Die innere Funktion akzeptiert das Argument als *args und **kwargs, was bedeutet, dass ein Tupel von Positionsargumenten oder ein Wörterbuch von Schlüsselwortargumenten beliebiger Länge übergeben werden kann. Dies macht es zu einem allgemeinen Dekorator, der eine Funktion mit einer beliebigen Anzahl von Argumenten dekorieren kann.
Verketten von Dekorateuren
Vereinfacht ausgedrückt bedeutet die Verkettung von Dekoratoren, dass eine Veranstaltung mit mehreren Dekoratoren dekoriert wird.
Beispiel:
Python3
# code for testing decorator chaining> def> decor1(func):> >def> inner():> >x>=> func()> >return> x>*> x> >return> inner> def> decor(func):> >def> inner():> >x>=> func()> >return> 2> *> x> >return> inner> @decor1> @decor> def> num():> >return> 10> @decor> @decor1> def> num2():> >return> 10> > print>(num())> print>(num2())> |
>
>
Ausgabe:
400 200>
Das obige Beispiel ähnelt dem Aufruf der Funktion als –
decor1(decor(num)) decor(decor1(num2))>