flasque - décorateur d'autorisation utilisateur de flacon
PHP中文网
PHP中文网 2017-05-18 10:50:23
0
2
689

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)
PHP中文网
PHP中文网

认证高级PHP讲师

répondre à tous(2)
迷茫

Vous devez d'abord comprendre le principe des décorateurs :

@abcd
def f():
    pass

équivaut en fait à l'énoncé suivant :

def f():
    pass
f=abcd(f)

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

@permission_required(permission)
def old():
    pass

équivaut à
def old():
    pass
old = permission_required(permission)(old)

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 :

old = permission_required(permission)(old)
-> old = decorator(old)
-> old = decorated_function
给我你的怀抱

J'espère que le code suivant vous sera utile

from functools import wraps

def permission_required(permission):
    """返回装饰器,装饰器中使用入参 permission
    """
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not permission:
                print '403'
                return
            return f(*args, **kwargs)
        return decorated_function
    return decorator


def admin_required_true(f):
    """装饰器函数,返回装饰器
    """
    return permission_required(True)(f)

def admin_required_false(f):
    """装饰器函数,返回装饰器
    """
    return permission_required(False)(f)

@admin_required_true
def foo():
    """使用装饰器
    """
    print 'foo'
    
@admin_required_false
def bar():
    """使用装饰器
    """
    print 'bar'

foo()
bar()

Résultat de l'exécution :

foo
403
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal