Je veux construire des classes pour être utilisés comme décorateurs avec intacts les principes suivants:cours de décorateur en Python
- Il devrait être possible d'empiler plusieurs de ces décorateurs de classe au-dessus de 1 fonction.
- Le pointeur de nom de fonction résultant doit être impossible à distinguer de la même fonction sans décorateur, sauf peut-être pour quel type/classe il est.
- La commande des décorateurs ne devrait être pertinente que si les décorateurs l'exigent. C'est à dire. décorateurs indépendants pourraient être appliqués dans n'importe quel ordre.
C'est un projet Django, et le cas particulier, je travaille maintenant la méthode a besoin de 2 décorateurs, et apparaissent en fonction de python normal:
@AccessCheck
@AutoTemplate
def view(request, item_id) {}
@AutoTemplate change la fonction afin Au lieu de renvoyer une réponse HttpResponse, elle renvoie simplement un dictionnaire à utiliser dans le contexte. Un RequestContext est utilisé et le nom du modèle est déduit du nom et du module de la méthode. @AccessCheck ajoute des contrôles supplémentaires sur l'utilisateur en fonction de l'item_id.
Je suppose que c'est juste pour obtenir le bon constructeur et copier les attributs appropriés, mais quels sont ces attributs?
Le décorateur suivant ne fonctionne pas comme je le décris:
class NullDecl (object):
def __init__ (self, func):
self.func = func
def __call__ (self, * args):
return self.func (*args)
Comme il est démontré par le code suivant:
@NullDecl
@NullDecl
def decorated():
pass
def pure():
pass
# results in set(['func_closure', 'func_dict', '__get__', 'func_name',
# 'func_defaults', '__name__', 'func_code', 'func_doc', 'func_globals'])
print set(dir(pure)) - set(dir(decorated));
De plus, essayez d'ajouter "l'impression func nom." Dans le constructeur NullDecl, et il fonctionnera pour le premier décorateur, mais pas le second - car le nom sera manquant.
raffiné eduffy de répondre un peu, et il semble fonctionner assez bien:
class NullDecl (object):
def __init__ (self, func):
self.func = func
for n in set(dir(func)) - set(dir(self)):
setattr(self, n, getattr(func, n))
def __call__ (self, * args):
return self.func (*args)
def __repr__(self):
return self.func
+1 parce que je Je ne sais pas pourquoi quelqu'un a voté cette question. C'est une bonne question: la plupart des questions de décorateur sur SO n'utilisent pas les classes comme décorateurs. Quoi que l'on puisse penser utilise une classe au lieu d'une fonction, c'est une question valide et peut être entièrement appropriée au cas d'utilisation. –