Python >> Tutoriel Python >  >> Python

Présentation des décorateurs Python

Apprenez les décorateurs Python dans ce tutoriel.

Ajoutez des fonctionnalités à une fonction existante avec des décorateurs. C'est ce qu'on appelle la métaprogrammation.

Une fonction peut prendre une fonction en argument (la fonction à décorer ) et retourne la même fonction avec ou sans extension.

L'extension des fonctionnalités est parfois très utile, nous montrerons des exemples concrets plus loin dans cet article.

Les fonctions sont des objets

En Python, tout est un objet, y compris les fonctions. Cela signifie que les fonctions peuvent être transmises et renvoyées. Quand vous le voyez, cela peut sembler étrange au premier abord :

1
2
3
4
5
6
7
8
def hello():                                                                                                
print("Hello")

# even functions are objects
message = hello

# call new function
message()

Appelez les méthodes message() ou hello() et elles ont le même résultat. C'est parce qu'ils font référence au même objet.

Passons maintenant aux décorateurs.

Décorateurs

Exemple

Un décorateur prend une fonction, l'étend et retourne. Oui, une fonction peut retourner une fonction .

1
2
3
4
5
6
7
8
9
10
11
12
def hello(func):                                                                                            
def inner():
print("Hello ")
func()
return inner

def name():
print("Alice")


obj = hello(name)
obj()

Dans l'exemple ci-dessus, hello() est un décorateur.

Dans la déclaration

1
obj = hello(name)          

la fonction name() est décorée par la fonction hello().

Il encapsule la fonction dans l'autre fonction.

Exemple 2

Les fonctions peuvent être étendues en les enveloppant.

1
2
3
4
5
6
7
8
9
10
11
12
def who():                                                                                                  
print("Alice")

def display(func):
def inner():
print("The current user is : ", end="")
func()
return inner

if __name__ == "__main__":
myobj = display(who)
myobj()

La fonction who() est décorée par display().

Sucre syntaxique

Les décorateurs sont courants et peuvent être simplifiés. Bien qu'il fasse exactement la même chose, son code est juste plus propre.

Python peut simplifier l'utilisation des décorateurs avec le symbole @ .

1
2
3
4
5
6
@hello                                                                                                      
def name():
print("Alice")

if __name__ == "__main__":
name()

Cela produira exactement la même chose, mais c'est une façon plus propre d'écrire le code.

Restez avec moi. L'appel

1
2
@hello                                                                                                      
def name():

est juste une façon plus simple d'écrire:
1
obj = hello(name)          

Dans les deux cas, nous appliquons le décorateur à une fonction.

Arguments

Les paramètres peuvent être utilisés avec des décorateurs. Si vous avez une fonction qui imprime la somme a + b, comme ceci

1
2
3
def sumab(a,b):                                                                                             
summed = a + b
print(summed)

Vous pouvez l'envelopper dans une fonction de décorateur.
L'exemple ci-dessous montre comment procéder :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def pretty_sumab(func):                                                                                     
def inner(a,b):
print(str(a) + " + " + str(b) + " is ", end="")
return func(a,b)

return inner

@pretty_sumab
def sumab(a,b):
summed = a + b
print(summed)

if __name__ == "__main__":
sumab(5,3)

La fonction sumab est enveloppée par la fonction jolie_sumab. Ceci est indiqué par le symbole @ au-dessus.

Appelez la fonction sumab et vérifiez que la logique des fonctions sumab et jolie_sumab est exécutée, avec des paramètres.

Exemples du monde réel

Cas d'utilisation :mesure du temps

Un décorateur peut être utilisé pour mesurer le temps d'exécution d'une fonction.

Si vous définissez une fonction simple qui dort,

1
2
def myFunction(n):                                                                                                        
time.sleep(n)

Vous pouvez ensuite mesurer le temps que cela prend simplement en ajoutant la ligne @measure_time

Un exemple ci-dessous :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time                                                                                                               

def measure_time(func):

def wrapper(*arg):
t = time.time()
res = func(*arg)
print("Function took " + str(time.time()-t) + " seconds to run")
return res

return wrapper

@measure_time
def myFunction(n):
time.sleep(n)

if __name__ == "__main__":
myFunction(2)

Cela affichera le temps qu'il a fallu pour exécuter la fonction myFunction(). Ce qui est cool, c'est d'ajouter une ligne de code @measure_time nous pouvons maintenant mesurer le temps d'exécution du programme.

Cas d'utilisation :application Web
Prenons le cas d'utilisation des applications Web. Lorsque vous créez une application Web dans Flask, vous écrivez toujours des routes d'URL.

Chaque itinéraire correspond à une certaine page de l'application Web.
L'ouverture de la page /about peut appeler la méthode about_page().

1
2
3
@app.route("/about")
def about_page():
return "Website about nachos"

Dans ce cas, il utilise le symbole @ pour la décoration.

Téléchargez des exemples et des exercices