Python中的装饰器类
我希望构造类作为装饰器使用,并保持以下原则不变:Python中的装饰器类,python,decorator,Python,Decorator,我希望构造类作为装饰器使用,并保持以下原则不变: 应该可以在一个函数的顶部堆叠多个这样的类装饰器 生成的函数名指针应该与没有修饰符的同一个函数不可区分,除了它是哪种类型/类 除非装饰师实际授权,否则订购装饰师不应相关。独立的装饰师可以按任何顺序使用 这是针对Django项目的,我现在正在处理的具体案例需要2个decorator,并显示为一个普通python函数: @AccessCheck @AutoTemplate def view(request, item_id) {} @AutoTemp
@AccessCheck
@AutoTemplate
def view(request, item_id) {}
@AutoTemplate更改了函数,因此它不返回HttpResponse,而只返回一个字典,以便在上下文中使用。使用RequestContext,并根据方法名和模块推断模板名
@AccessCheck根据项目id添加对用户的附加检查
我猜这只是为了得到正确的构造函数并复制适当的属性,但是这些属性是什么呢
以下装饰器将无法按照我的描述工作:
class NullDecl (object):
def __init__ (self, func):
self.func = func
def __call__ (self, * args):
return self.func (*args)
如以下代码所示:
@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));
另外,尝试在NullDecl构造函数中添加“print func.name”,它将适用于第一个decorator,但不会缺少第二个-as名称
对eduffy的回答进行了一点精炼,似乎效果很好:
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
不做任何事的装饰器类如下所示:
class NullDecl (object):
def __init__ (self, func):
self.func = func
for name in set(dir(func)) - set(dir(self)):
setattr(self, name, getattr(func, name))
def __call__ (self, *args):
return self.func (*args)
然后您可以正常应用它:
@NullDecl
def myFunc (x,y,z):
return (x+y)/z
帮助您编写保留签名的装饰器
并且可能会为修饰符提供有用的示例。要创建一个修饰符来包装函数,使其与原始函数无法区分,请使用
functools.wrapps
例如:
def mydecorator(func):
@functools.wraps(func):
def _mydecorator(*args, **kwargs):
do_something()
try:
return func(*args, **kwargs)
finally:
clean_up()
return _mydecorator
# ... and with parameters
def mydecorator(param1, param2):
def _mydecorator(func):
@functools.wraps(func)
def __mydecorator(*args, **kwargs):
do_something(param1, param2)
try:
return func(*args, **kwargs)
finally:
clean_up()
return __mydecorator
return _mydecorator
(我个人的偏好是使用函数而不是类创建装饰器)
装饰师的顺序如下:
@d1
@d2
def func():
pass
# is equivalent to
def func():
pass
func = d1(d2(func))
+1因为我不知道为什么有人否决了这个问题。这是一个很好的问题:大多数的decorator问题,所以不要使用类作为decorator。不管你怎么想,使用类而不是函数,这都是一个有效的问题,可能完全适合这个用例。我想我读到有人建议为装饰师使用类,但我想这是个糟糕的建议。如果你想使用类,我不知道你把@functools.wrapps放在哪里了。我觉得作为装饰者的功能更像蟒蛇。代码更短。在您的参数示例中,“func”来自哪里?它不在mydecorator()的参数列表中……您应用@decorator(param1,param2)def func:pass-decorator(param1,param2)返回将用于装饰的实际函数。这里有3个级别的嵌套函数。我添加了自己的修复程序,因此它可以正常工作。感谢您的帮助,通常有助于开始非常基本的操作。也许还有一个地方可以将
**kwargs
添加到定义def\uu调用(self,*args):
(以及以后调用self.func
)中?如何使用functool.wrapps?