Maison  >  Article  >  développement back-end  >  Explication détaillée des décorateurs python

Explication détaillée des décorateurs python

藏色散人
藏色散人original
2020-02-13 11:41:204923parcourir

Explication détaillée des décorateurs python

Explication détaillée du décorateur python

Analyse détaillée du décorateur python

Quoi Est-ce un décorateur ?

Apprentissage recommandé : Tutoriel vidéo Python

Les décorateurs Python (décorateurs fonctionnels) sont des fonctions utilisées pour étendre les fonctionnalités de la fonction d'origine. Le but est de quand. en changeant le nom de la fonction d'origine (ou le nom de la classe), ajoutez de nouvelles fonctions à la fonction.

La particularité de cette fonction est que sa valeur de retour est également une fonction. Cette fonction est une fonction avec la fonction "originale" intégrée

De manière générale, si nous le voulons. étendre le code de la fonction d'origine, le moyen le plus direct est d'envahir le code et de le modifier, par exemple :

import time
def f():
    print("hello")
    time.sleep(1)
    print("world")  

C'est notre fonction la plus originale, puis nous essayons d'enregistrer le total temps d'exécution de cette fonction, alors Le moyen le plus simple est de changer le code d'origine :

import time
def f():
    start_time = time.time()
    print("hello")
    time.sleep(1)
    print("world")
    end_time = time.time()
    execution_time = (end_time - start_time)*1000
    print("time is %d ms" %execution_time)

Mais dans le travail réel, parfois le code principal ne peut pas être modifié directement, donc sans changer le code d'origine , nous Vous pouvez définir une autre fonction (mais la fonction doit être à nouveau exécutée pour prendre effet)

import time
def deco(func):
    start_time = time.time()
    f()
    end_time = time.time()
    execution_time = (end_time - start_time)*1000
    print("time is %d ms" %execution_time)
def f():
    print("hello")
    time.sleep(1)
    print("world")
if __name__ == '__main__':
    deco(f)
    print("f.__name__ is",f.__name__)
    print()

Ici, nous définissons une fonction déco, dont le paramètre est une fonction, puis intégrons le timing dans cette fonction . Mais si vous souhaitez étendre les fonctionnalités de ces dizaines de millions de fonctions,

signifie exécuter la fonction deco() dix millions de fois, donc ce n'est pas idéal ! essayez d'utiliser des décorateurs pour y parvenir. Regardez d'abord l'apparence originale du décorateur

import time
def deco(f):
    def wrapper():
        start_time = time.time()
        f()
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" %execution_time )
    return wrapper
@deco
def f():
    print("hello")
    time.sleep(1)
    print("world")
if __name__ == '__main__':
    f()

La fonction déco ici est le décorateur le plus original. Son paramètre est une fonction, et le retour. value est aussi une fonction.

La fonction f() en tant que paramètre est exécutée à l'intérieur de la fonction de retour wrapper(). Ajoutez ensuite @deco devant la fonction f(), et le

f(. ) équivaut à être injecté. Avec la fonction timing, désormais tant que f() est appelée, elle est transformée en une "nouvelle fonction avec plus de fonctions",

(pas besoin de répéter l'originale). fonction)

extension. 1 : Décorateur avec paramètres fixes

import time
def deco(f):
    def wrapper(a,b):
        start_time = time.time()
        f(a,b)
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" % execution_time)
    return wrapper
@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
if __name__ == '__main__':
    f(3,4)

Extension 2 : Décorateur sans paramètres fixes

import time
def deco(f):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        f(*args, **kwargs)
        end_time = time.time()
        execution_time_ = (end_time - start_time)*1000
        print("time is %d ms" %execution_time)
    return wrapper
@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
@deco
def f2(a,b,c):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b+c))
if __name__ == '__main__':
    f2(3,4,5)
    f(3,4)

Extension 3 : Utiliser plusieurs décorateurs pour décorer une fonction

import time
def deco01(f):
    def wrapper(*args, **kwargs):
        print("this is deco01")
        start_time = time.time()
        f(*args, **kwargs)
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" % execution_time)
        print("deco01 end here")
    return wrapper
def deco02(f):
    def wrapper(*args, **kwargs):
        print("this is deco02")
        f(*args, **kwargs)
        print("deco02 end here")
    return wrapper
@deco01
@deco02
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
if __name__ == '__main__':
    f(3,4)
'''
this is deco01
this is deco02
hello,here is a func for add :
result is 7
deco02 end here
time is 1003 ms
deco01 end here
'''

Ordre d'appel du décorateur

Les décorateurs peuvent être utilisés en superposition, alors quel est l'ordre du code après avoir utilisé les décorateurs

Pour la syntaxe "@" en Python ? ? Sugar, l'ordre dans lequel les décorateurs sont appelés est l'inverse de l'ordre déclaré à l'aide du @ sucre syntaxique

Dans cet exemple, "f(3, 4) = deco01(deco02(f(3, 4) )))".

Décorateurs intégrés Python

Il existe trois décorateurs intégrés en Python, tous liés aux classes : staticmethod , classmethod et property .

staticmethod est une méthode statique de classe. La différence entre elle et les méthodes membres est qu'elle n'a pas de paramètre self et peut être appelée sans instancier la classe. classmethod et méthodes membres est que Le premier paramètre reçu n'est pas self (un pointeur vers une instance de classe), mais cls (le type spécifique de la classe actuelle)

property signifie propriété, indiquant des informations accessibles directement via une instance de classe

Je ne présenterai pas ici la méthode statique et la méthode de classe. Jetons un coup d'œil à la propriété à travers un exemple.

Notez que pour les classes Python de nouveau style, si la fonction membre décorée par le décorateur "@var.setter" ci-dessus est supprimée, Foo L'attribut var est une lecture. -only attribut, et une exception sera levée lors de l'attribution d'une valeur à l'aide de "foo.var = 'var 2′". Cependant, pour la classe Python classique, les attributs déclarés ne sont pas en lecture seule, donc même si le décorateur "@var.setter" est supprimé, aucune erreur ne sera signalée. Explication détaillée des décorateurs python

Résumé

Cet article présente quelques utilisations des décorateurs Python Le code du décorateur est relativement facile à comprendre. C’est facile à comprendre à condition de le mettre en pratique à travers quelques exemples.

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!

Déclaration:
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