logo

Dekoratører i Python

Dekoratører er et meget kraftfuldt og nyttigt værktøj i Python, da det giver programmører mulighed for at ændre adfærden for en funktion eller klasse. Dekoratorer giver os mulighed for at indpakke en anden funktion for at udvide den indpakkede funktions adfærd uden at ændre den permanent. Men før vi dykker dybt ned i dekoratører, lad os forstå nogle begreber, der vil være nyttige, når vi lærer dekoratører.

Førsteklasses objekter
I Python er funktioner førsteklasses genstande hvilket betyder at funktioner i Python kan bruges eller videregives som argumenter.
Egenskaber for førsteklasses funktioner:

  • En funktion er en instans af objekttypen.
  • Du kan gemme funktionen i en variabel.
  • Du kan overføre funktionen som en parameter til en anden funktion.
  • Du kan returnere funktionen fra en funktion.
  • Du kan gemme dem i datastrukturer såsom hashtabeller, lister, …

Overvej nedenstående eksempler for bedre forståelse.



Eksempel 1: Behandling af funktionerne som objekter.

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'>))>

>

>

Produktion:

HELLO HELLO>

I ovenstående eksempel har vi tildelt funktionen shout til en variabel. Dette vil ikke kalde funktionen i stedet for det tager funktionsobjektet, der refereres til af et råb, og opretter et andet navn, der peger på det, råb.

Eksempel 2: Sender funktionen som et 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)>

>

>

Produktion:

HI, I AM CREATED BY A FUNCTION PASSED AS AN ARGUMENT. hi, i am created by a function passed as an argument.>

I ovenstående eksempel tager velkomstfunktionen en anden funktion som parameter (råb og hvisk i dette tilfælde). Funktionen, der sendes som et argument, kaldes derefter inde i funktionen hilsen.

Eksempel 3: Returnerer funktioner fra en anden funktion.

Python3




skriv json til filen python
# 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>))>

>

>

Produktion:

25>

I ovenstående eksempel har vi oprettet en funktion inde i en anden funktion og derefter returneret den funktion, der er oprettet inde.
Ovenstående tre eksempler skildrer de vigtige begreber, der er nødvendige for at forstå dekoratører. Efter at have gennemgået dem, lad os nu dykke dybt ned i dekoratører.

Dekoratører

Som nævnt ovenfor bruges dekoratørerne til at ændre funktions- eller klasses adfærd. I Decorators tages funktioner som argumentet ind i en anden funktion og kaldes derefter inde i indpakningsfunktionen.

Syntaks for dekoratør:

@gfg_decorator def hello_decorator(): print('Gfg') '''Above code is equivalent to - def hello_decorator(): print('Gfg') hello_decorator = gfg_decorator(hello_decorator)'''>

I ovenstående kode er gfg_decorator en funktion, der kan kaldes, som vil tilføje noget kode oven på en anden funktion, som kan kaldes, hello_decorator-funktionen og returnere indpakningsfunktionen.

Dekoratør kan ændre opførsel :

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()>

>

>

Produktion:

Hello, this is before function execution This is inside the function !! This is after function execution>

Lad os se adfærden af ​​ovenstående kode, og hvordan den kører trin for trin, når funktionen_til_benyttes kaldes.

Lad os springe til et andet eksempel, hvor vi nemt kan finde ud af det udførelsestiden for en funktion ved hjælp af en dekoratør.

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>)>

>

>

Produktion:

3628800 Total time taken in : factorial 2.0061802864074707>

Hvad hvis en funktion returnerer noget, eller et argument sendes til funktionen?

I alle ovenstående eksempler returnerede funktionerne ikke noget, så der var ikke et problem, men man kan have brug for den returnerede værdi.

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))>

>

>

Produktion:

before Execution Inside the function after Execution Sum = 3>

I ovenstående eksempel kan du bemærke en stor forskel i parametrene for den indre funktion. Den indre funktion tager argumentet som *args og **kwargs, hvilket betyder, at en række positionsargumenter eller en ordbog med nøgleordsargumenter kan sendes af enhver længde. Dette gør det til en generel dekoratør, der kan dekorere en funktion med et vilkårligt antal argumenter.

Kæde dekoratører

I enklere vendinger betyder kæde dekoratører at dekorere en funktion med flere dekoratører.

tekstindpakning css

Eksempel:

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())>

>

>

Produktion:

400 200>

Ovenstående eksempel svarer til at kalde funktionen som -

decor1(decor(num)) decor(decor1(num2))>