Maison > développement back-end > Tutoriel Python > Que sont les décorateurs en Python ? Introduction aux décorateurs en Python

Que sont les décorateurs en Python ? Introduction aux décorateurs en Python

不言
Libérer: 2018-09-13 16:50:24
original
2923 Les gens l'ont consulté

Le contenu de cet article porte sur que sont les décorateurs en Python ? L'introduction des décorateurs dans Python a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer, j'espère que cela vous sera utile.

1. Qu'est-ce qu'un décorateur ?

Un décorateur est essentiellement une fonction Python qui permet à d'autres fonctions de fonctionner sans aucune modification de code. la valeur du décorateur est également un objet fonction.

Les décorateurs améliorent la fonctionnalité des parties du code principal sans modifier le code principal. Par exemple, insérez les journaux, la vérification des autorisations, le traitement des transactions et d'autres scénarios avant les fonctions.
Et vous pouvez extraire une grande quantité de code similaire qui n'a rien à voir avec les fonctions de fonction et le réutiliser.

2. Implémentation précoce : les décorateurs qui ne sont pas des décorateurs

  • Une fonction en Python peut également être considérée comme un objet et peut être affectée à une variable et appelez la fonction via la variable.

Par exemple :

def foo():
   print("2017-06-08")
f = foo    # 将函数赋值给变量,f为函数对象
f()
# 返回结果:
2017-06-08
Copier après la connexion

3. La syntaxe sugar @ implémente un décorateur simple

Supposons maintenant que vous souhaitiez améliorer la fonction foo(), par exemple en imprimant les journaux avant les appels de fonction. Mais je ne veux pas modifier la définition de la fonction foo(). Cette façon d'ajouter dynamiquement des fonctionnalités pendant l'exécution du code est appelée « décorateur ».
est le suivant :

def testfunc(func):
    print('testfunc')
    def wrapper():
        print("%s %s() called" %(time.ctime(),func.__name__))
        return func()
    return wrapper
@testfunc 
def foo():
    print('foo1()')

foo()  # 相当于执行testfunc(foo) ->wrapper(foo) -> foo()
Copier après la connexion

Résultat de l'exécution :

testfunc
Wed Sep 12 15:01:13 2018 foo() called
foo1()
Copier après la connexion

Explication : Avant d'exécuter foo(), exécutez testfunc (( foo), puis exécutez wrapper() et appelez foo() lui-même lors du retour.

4. Les décorateurs qui reçoivent des types spécifiques de paramètres

  • Les décorateurs peuvent recevoir des paramètres lorsque la fonction renvoyée par le décorateur est appelée, c'est-à-dire. La fonction d'emballage est appelée, en passant les paramètres dans la fonction d'emballage, qui transmet les paramètres à la fonction décorée.

est le suivant :

def testfunc_with_args(func):
    def wrapper_argus(arg1, arg2):
        print("I got args! Look:", arg1, arg2)
        func(arg1, arg2)
    return wrapper_argus
@testfunc_with_args
def full_name(first_name, last_name):  # 带参数,将参数传给被装饰的函数
    print("My name is", first_name, last_name)

full_name("Peter", "Venkman")  # 调用
Copier après la connexion

Résultat de l'exécution :

I got args! Look: Peter Venkman
My name is Peter Venkman
Copier après la connexion

5. Décorateur avec paramètres indéfinis

Quand il y a plusieurs fonctions qui doivent appeler le décorateur, mais que les paramètres des fonctions sont différents, comment l'implémenter ? Il ne peut y avoir une fonction correspondant à un décorateur. A l’heure actuelle, il peut être implémenté à l’aide d’un décorateur à paramètres variables.
Comme suit :

def log(func):
    def wrapper(*args,**kwargs):        # 可接受各种参数
        print('call %s():'% func.__name__)
        return func(*args,**kwargs)     # 返回一个函数
    return wrapper                      # 装饰器返回一个函数,进入到wrapper()

@log      # @log放到now()的定义处,相当于执行语句:now = log(now)
def now_1(a,b):
    print('now()1:a+b = ',a+b)
@log
def now_2(a,b,c):
    print('now_2():a+b+c = ',a+b+c)

now_1(1,2)
now_2(1,2,3)
Copier après la connexion

Exécutez-le~

6. Plusieurs décorateurs

Lorsqu'une fonction souhaite ajouter plusieurs éléments lors de l'utilisation. fonctions, vous pouvez envisager d'utiliser des décorateurs multicouches, mais vous devez faire attention à l'ordre d'exécution des décorateurs.
Par exemple :

# 注意代码的执行顺序
def deco_1(func):
    print('------111111------')
    def wrapper(*args,**kwargs):    # 包裹函数,参数与原函数的参数一致
        print('start: this is deco_1.')
        func(*args,**kwargs)
        print('end: deco_1.')
    return wrapper  # 返回值是一个包裹函数
def deco_2(func):
    print('------222222------')
    def wrapper(*args,**kwargs):
        print('start: this is deco_2.')
        func(*args,**kwargs)
        print('end: deco_2.')
    return wrapper

@deco_1
@deco_2
def now_1(a,b):
    print('now()1:a+b = ',a+b)

now_1(1,2)
Copier après la connexion

Résultat d'exécution :

# 结果,注意执行顺序:
------222222------
------111111------
start: this is deco_1.
start: this is deco_2.
now()1:a+b =  3
end: deco_2.
end: deco_1.
Copier après la connexion

7. Le décorateur lui-même a des paramètres

En plus d'être étant donné La fonction décorée prend des paramètres, et le décorateur lui-même peut également prendre des paramètres.

def logging(level):
    def wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print("[{level}]: enter function {func}()".format(level=level, func=func.__name__))
            return func(*args, **kwargs)
        return inner_wrapper
    return wrapper
    
@logging(level='INFO')
def say(something):
    print("say {}!".format(something))

@logging(level='DEBUG')
def do(something):
    print("do {}...".format(something))

say('hello')
do("my work")
Copier après la connexion

Résultat de l'exécution :

# 执行结果:
[INFO]: enter function say()
say hello!
[DEBUG]: enter function do()
do my work...
Copier après la connexion

Recommandations associées :

Explication détaillée des décorateurs en python

Explication détaillée de divers décorateurs en Python

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