Maison  >  Article  >  développement back-end  >  Compréhension approfondie des décorateurs Python

Compréhension approfondie des décorateurs Python

高洛峰
高洛峰original
2017-01-23 14:41:541094parcourir

Introduction aux décorateurs :

Decorator est une syntaxe Python avancée. Les décorateurs peuvent traiter une fonction, une méthode ou une classe. En Python, nous disposons de nombreuses façons de traiter les fonctions et les classes. Par exemple, dans les fermetures Python, nous considérons les objets fonction comme le résultat de retour d'une certaine fonction. Par rapport à d’autres méthodes, la syntaxe du décorateur est simple et le code est très lisible. Par conséquent, les décorateurs sont largement utilisés dans les projets Python.

Le décorateur est apparu pour la première fois dans Python 2.5. Il était initialement utilisé pour traiter des objets appelables tels que des fonctions et des méthodes (ces objets sont définis avec une méthode __call__). Dans Python 2.6 et les versions ultérieures de Python, les décorateurs sont également utilisés pour traiter les classes.

Le décorateur est principalement utilisé pour envelopper des fonctions, pour certaines fonctions courantes, telles que : l'impression du journal, la synchronisation des fonctions, l'authentification de l'identité. Nous pouvons utiliser des décorateurs pour y parvenir, ce qui peut réduire la complexité de l'ensemble du programme et réduire la quantité de code dans le programme.

C'est en fait une fonction. La différence est qu'elle prend une fonction comme paramètre et renvoie une version alternative de la fonction.

Regardez un exemple simple ci-dessous :

def add_number(func):
def adder(arg):
return func(arg)+100
return adder
def f(x):
return x
f=add_number(f)
print f(20)

add_number est une fonction de décorateur qui accepte une fonction (f) comme paramètre et renvoie une autre fonction (additionneur) est affecté à la fonction d'origine de cette façon, la fonction d'origine réalise la fonction d'addition sans ajouter de code supplémentaire.

Il s'agit de la mise en œuvre originale du décorateur.

Mais cette méthode est encore un peu gênante. Après tout, nous tournons toujours en cercle et utilisons f=add_number(f) pour réaffecter la fonction d'origine.

En fait, les méthodes suivantes peuvent être utilisées pour simplifier la référence aux décorateurs en Python.

def add_number(func):
def adder(arg):
return func(arg)+100
return adder
@add_number
def f(x):
return x
print f(20)

Cela ne nécessite qu'un simple appel @add_numbe. N'est-ce pas pratique ? C'est beaucoup plus simple et n'envahit fondamentalement pas le code d'origine.

Bon, tout le monde a remarqué qu'en tant que décorateur, il n'y a que deux paramètres acceptés à chaque fois : les fonctions et les paramètres de fonction, mais le format d'écriture est fondamentalement le même. Y a-t-il un moyen de simplifier ce genre d'écriture ?

Oui, Python fournit un package de décorateur, qui peut grandement simplifier l'écriture des décorateurs.

Donc, la troisième méthode de mise en œuvre est :

from decorator import decorator
@decorator
def wrapper(func,arg):
return func(arg)+100
@wrapper
def f(x):
return x
print f(20)

Oh, c'est en effet plus simple~

Au-dessus du les exemples acceptent tous un paramètre. En fait, la fonction elle-même peut accepter des paramètres variables.

Par exemple :

@decorator
def wrapper(f,arg1,*args,**kwargs):
print "I am just a wrapper~"
return f(arg1,*args,**kwargs)
@wrapper
def f(arg1,*args,**kwargs):
print arg1
for eacheArg in args:
print 'non-keyword arg:',eacheArg
for eachKw in kwargs.keys():
print 'keyword arg: %s:%d' % (eachKw,kwargs[eachKw])
args=('Joy','Steve')
kwargs={"age":20}
f('China',*args,**kwargs)

Le résultat de sortie est :

I am just a wrapper~
China
non-keyword arg: Joy
non-keyword arg: Steve
keyword arg: age:20

À propos de *args ,* La différence entre *kwargs, les deux peuvent être utilisés pour représenter des paramètres de longueur variable. C'est juste que le premier est représenté par Yuanzu et n'a pas de valeur clé, tandis que le second est un dictionnaire avec une valeur clé. Les deux peuvent être utilisés dans la même fonction, cependant, *args doit apparaître avant **kwargs.

Par exemple :

def test_var_args_call(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
args=(1,2,3)
kwargs ={"arg1":"1","arg3": 3, "arg2": "2"}
test_var_args_call(*args)
print '-----------------'
test_var_args_call(**kwargs)

Les deux obtiennent le même effet.

Le dernier exemple consiste à décorer une fonction en affichant le temps d'exécution de la fonction

import time
def log(func):
def wrapper(*args, **kw):
print '[%s] %s() was called...' % (time.ctime(),func.__name__)
return func(*args, **kw)
return wrapper
@log
def foo():
pass
for i in range(4):
foo()
time.sleep(1)

Le résultat de sortie est le suivant :

[Wed Jul 27 09:17:23 2016] foo() was called...
[Wed Jul 27 09:17:24 2016] foo() was called...
[Wed Jul 27 09:17:25 2016] foo() was called...
[Wed Jul 27 09:17:26 2016] foo() was called...

Ce qui précède est la compréhension approfondie des décorateurs Python présentée par l'éditeur. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et le. l'éditeur vous répondra à temps. Je voudrais également vous remercier tous pour votre soutien au site Web PHP chinois !

Pour une compréhension plus approfondie des articles liés au décorateur Python, veuillez prêter attention au site Web PHP 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