Après avoir lu le livre, j'ai trouvé que ce code est un peu déroutant et le décorateur est un peu flou. J'espère que vous pourrez m'aider à analyser ce code ! !
from functools import wraps
from flask import abort
from flask_login import current_user
from .models import Permission
def permission_required(permission):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not current_user.can(permission):
abort(403)
return f(*args, **kwargs)
return decorated_function
return decorator
def admin_required(f):
return permission_required(Permission.ADMINISTER)(f)
Vous devez d'abord comprendre le principe des décorateurs :
équivaut en fait à l'énoncé suivant :
Nous avons maintenant une fonction abcd. L'essence de cette fonction est la suivante : elle accepte une autre fonction comme paramètre et renvoie une fonction. (Quant à l'utilisation de la fonction renvoyée, cela dépend de vous). Pour le moment, abcd n'est qu'une fonction, pas un modificateur.
Et parce que la demande suivante est très courante : il existe une ancienne fonction, et nous souhaitons définir une nouvelle fonction. Cette nouvelle fonction a généralement une fonction similaire à l'ancienne fonction, mais a un peu plus de nouvelles fonctions, comme l'impression d'un. date et juger une personne autorisations ou quelque chose. Ensuite, l'ancienne fonction sera certainement appelée pendant le processus de définition d'une nouvelle fonction. Cependant, la nouvelle fonction ne change en réalité pas grand-chose, et l'ancienne fonction est souvent inutile (car nous utilisons généralement la nouvelle fonction plus tard), donc pour. empêcher l'espace de noms de changer Pour éviter toute confusion et faciliter le développement, nous pouvons simplement utiliser le nom de l'ancienne fonction pour représenter la nouvelle fonction, c'est-à-dire qu'après avoir défini une nouvelle fonction, nous remplaçons son nom par le f précédent et le précédent. f est Plus rien. Nous pouvons donc faire ceci : Définir une fonction abcd, qui accepte une fonction f et renvoie une nouvelle fonction, puis attribue sa valeur de retour (nouvelle fonction) à f (le nom de la fonction en python peut également se voir attribuer une valeur, devenant une autre fonction). C'est en fait ce que fait mon deuxième morceau de code ci-dessus. Parce que cette exigence est si courante, Python définit une syntaxe spécifiquement pour cela. Ne voulez-vous pas f=abcd(f) à chaque fois ? Ajoutez simplement @abcd devant l'instruction def de f. N'écrivez pas la phrase suivante à chaque fois. C'est non seulement gênant, mais aussi facile à mal comprendre. . A cette époque, abcd devient le décorateur. En comprenant cette relation d'équivalence, votre fonction sera plus facile à comprendre : lorsque vous l'utiliserez quelque part, elle ressemblera à ceci
équivaut à
Les priorités sont les mêmes, les opérations se font de gauche à droite et la fonction définie ici est calculée en premier.
Le processus est le suivant :J'espère que le code suivant vous sera utile
Résultat de l'exécution :