recherche

Maison  >  Questions et réponses  >  le corps du texte

flasque - décorateur d'autorisation utilisateur de flacon

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中文网2780 Il y a quelques jours687

répondre à tous(2)je répondrai

  • 迷茫

    迷茫2017-05-18 10:52:23

    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

    répondre
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-18 10:52:23

    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

    répondre
    0
  • Annulerrépondre