Maison > développement back-end > Tutoriel Python > Que signifie décorateur python ? Comment utiliser les décorateurs Python ?

Que signifie décorateur python ? Comment utiliser les décorateurs Python ?

PHP中文网
Libérer: 2017-06-20 14:30:51
original
1895 Les gens l'ont consulté

Python --- explication détaillée des décorateurs

Définition :

Essentiellement une fonction. Sa fonction est de décorer une autre fonction (c'est-à-dire la fonction décorée) et d'ajouter des fonctionnalités à la fonction décorée. Le principe est que le code source et la méthode d'appel de la fonction décorée ne peuvent pas être modifiés. Une telle fonction est appelée décorateur.

Analyse :

Parlons ci-dessous Pas grand chose à dire, expliquez-le simplement dans le code. Ci-dessous se trouve une fonction.

      b=1+2
Copier après la connexion

Résultat du programme :

————————

3

————————

Maintenant je souhaite ajouter une phrase explicative à cette fonction, comme suit, on peut écrire un décorateur :

 1 #原函数 2 def add(): 3     a=1+2 4     print(a)  
 5 #装饰器 6 def decorator(func): 7     def warpper(): 8         print("1+2的结果是:") 9         func()10     return warpper11 #注意此句   12 add=decorator(add)13 #调用函数14 add()
Copier après la connexion

Résultat du programme :

——————————

Le résultat de 1+2 est :

3

——————————

De cette façon, nous avons atteint notre objectif avec succès. Faites attention à cette phrase à la ligne 12. Cette phrase transmet l'objet fonction add dans la fonction decorator() et renvoie une nouvelle variable de fonction. Ce nouvel objet fonction est réaffecté pour ajouter, afin qu'il puisse être garanti qu'il ne changera pas. La méthode d'appel de la fonction décorée reste inchangée. Il existe une manière plus élégante de remplacer l'instruction de la ligne 12 dans la syntaxe Python. Comme suit :

 1  #装饰器 2 def decorator(func): 3     def warpper(): 4         print("1+2的结果是:") 5         func() 6     return warpper 7  8 #add=decorator(add) 9 #原函数10 @decorator#换成@符号11 def add():12     a=1+213     print(a)14 #调用函数15 add()
Copier après la connexion

Ajoutez "@xxx" directement devant la fonction décorée (xxx est le nom de la fonction Décorateur) peut être

Que dois-je faire si la fonction décorée a des paramètres ?

Et si la fonction décorée a des paramètres ? Comment devons-nous travailler ? Ne vous inquiétez pas, nous pouvons collecter des paramètres sous forme de paramètres indéfinis. L'exemple de code est le suivant :

 1 def decorator(func): 2     def warpper(*args,**kwargs): 3         print("相加的结果是:") 4         func(*args,**kwargs) 5     return warpper 6  7 @decorator 8 def add(x,y): 9     a=x+y10     print(a)11 12 add(2,3)
Copier après la connexion
程序输出:
——————————————————
相加的结果是:
5
——————————————————
Copier après la connexion

Écrivez un décorateur de vérification de page ci-dessous.

Nous savons tous que certaines pages de certains sites Web nécessitent que les utilisateurs se connectent avant de pouvoir y accéder, comme les trois fonctions suivantes (représentant respectivement trois pages) :

1 def index():2     print("welcome to the index page")3 def home():4     print("welcome to the home page")5 def bbs():6     print("welcome to the bbs page")7     return "I am the return contents"
Copier après la connexion

Si nous voulons maintenant ajouter une vérification à la page d'accueil et à la page bbs, il n'est évidemment pas possible de changer le code source maintenant. A ce moment nous pouvons utiliser des décorateurs, comme suit :

 1 username,passwd="jack","abc123"#模拟一个已登录用户 2 def decorator(func): 3     def warpper(*args,**kwargs): 4         Username=input("Username:").strip() 5         password=input("Password:").strip() 6         if username==Username and passwd==password: 7             print("Authenticate Success!") 8             func(*args,**kwargs) 9         else:10             exit("Username or password is invalid!")11     return warpper12 13 def index():14     print("welcome to the index page")15 @decorator16 def home():17     print("welcome to the home page")18 @decorator19 def bbs():20     print("welcome to the bbs page")21     return "I am the return contents"22 23 index()24 home()25 bbs()
Copier après la connexion

Résultats du programme :

————————

Bienvenue sur la page d'index #La page d'index peut être connectée directement sans vérification
Nom d'utilisateur : jack
Mot de passe :abc123
Authentification réussie #Situation de connexion
Bienvenue sur la page d'accueil !
Nom d'utilisateur : Jack #> ou erreur de nom d'utilisateur.
————————

Nous avons remarqué que bbs() a une valeur de retour Si nous changeons la dernière phrase du code ci-dessus (ligne 25) en « print(bbs() ) " puis regardez sa sortie :

————————

bienvenue sur la page d'index

Nom d'utilisateur :jack

Mot de passe : abc123
Authentifier le succès !
Bienvenue sur la page d'accueil
Nom d'utilisateur:jack
Mot de passe:abc123
Authentifier le succès !
Bienvenue sur la page bbs
Aucun Est-il devenu Aucun ? ? ?

————————

Que s'est-il passé ! La valeur de retour de bbs() est affichée comme None. comment ça? Cela ne changerait-il pas le code source de la fonction décorée ? Comment résoudre ce problème ?

Analysons-le :

Lorsque nous exécutons la fonction bbs, cela équivaut en fait à exécuter la fonction wrapper dans le décorateur. Après une analyse minutieuse du décorateur, nous avons constaté que la fonction wrapper a. pas de valeur de retour, donc afin de le laisser Pour garantir que la valeur de retour de la fonction décorée puisse être renvoyée correctement, le décorateur doit être modifié :

如图加上第8行的return就可以解决了。下面我们在看看改后的程序输出:

————————

welcome to the index page
Username:jack
Password:abc123
Authenticate Success!
welcome to the home page
Username:jack
Password:abc123
Authenticate Success!
welcome to the bbs page
I am the return contents   #bbs()的返回值得到了正确的返回

——-——————

好了,返回值的问题解决了.

 

既然装饰器是一个函数,那装饰器可以有参数吗?

答案是肯定的。我们同样可以给装饰器加上参数。比如还是上面的三个页面函数作为例子,我们可以根据不同页面的验证方式来给程序不同的验证,而这个验证方式可以以装饰器的参数传入,这样我们就得在装饰器上在嵌套一层函数 了:

 1 username,passwd="jack","abc123"#模拟一个已登录用户 2 def decorator(auth_type): 3     def out_warpper(func): 4         def warpper(*args,**kwargs): 5             Username=input("Username:").strip() 6             password=input("Password:").strip() 7             if auth_type=="local": 8                 if username==Username and passwd==password: 9                     print("Authenticate Success!")10                     return func(*args,**kwargs)11                 else:12                     exit("Username or password is invalid!")13             elif auth_type=="unlocal":14                 print("HERE IS UNLOCAL AUTHENTICATE WAYS")15         return warpper16     return out_warpper17 18 def index():19     print("welcome to the index page")20 @decorator(auth_type="local")21 def home():22     print("welcome to the home page")23 @decorator(auth_type="unlocal")24 def bbs():25     print("welcome to the bbs page")26     return "I am the return contents"27 28 index()29 home()30 bbs()
Copier après la connexion

 

输出:

————————

welcome to the index page
Username:jack
Password:abc123
Authenticate Success!
welcome to the home page
Username:jack
Password:abc123
HERE IS UNLOCAL AUTHENTICATE WAYS

————————

可见,程序分别加入了第2行和第16行和中间的根据auth_type参数的判断的相关内容后, 就解决上述问题了。对于上面的这一个三层嵌套的相关逻辑,大家可以在 pycharm里头加上断点,逐步调试,便可发现其中的道理。 

总结

要想学好迭代器就必须理解一下三条:

1.函数即变量(即函数对象的概念)

2.函数嵌套

3.函数式编程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal