我试图在芹菜@task装饰器之后应用装饰器,类似于。
@send_email
@task
def any_function():
print "inside the function"
我可以按照文档中推荐的方式使用它,即将装饰器放在任务装饰器之前,但在这种情况下,我想访问装饰器中的任务实例。
@send_email必须是一个类装饰器,这是我尝试的没有成功:
class send_email(object):
''' wraps a Task celery class '''
def __init__(self, obj):
self.wrapped_obj = obj
functools.update_wrapper(self, obj)
def __call__(self, *args, **kwargs):
print "call"
return self.wrapped_obj.__call__(*args, **kwargs)
def run(self, *args, **kwargs):
print "run"
return self.wrapped_obj.__call__(*args, **kwargs)
def __getattr__(self, attr):
if attr in self.__dict__:
return getattr(self, attr)
return getattr(self.wrapped_obj, attr)
我永远无法在调用或运行函数函数中获取print语句以显示在worker或调用者中。
如何在不使用基于类的任务定义的情况下装饰芹菜任务(因此装饰器将位于函数定义之上的@task之上。
感谢您的帮助!
米格尔
答案 0 :(得分:10)
任务装饰器不返回类,它返回一个实例。
您的问题似乎应该是“如何才能访问装饰器内的任务”,而不是如何首先应用装饰器。
在即将发布的3.1(开发版)中,您可以使用绑定任务来完成此任务:
def send_email(fun):
@wraps(fun)
def outer(self, *args, **kwargs):
print('decorated and task is {0!r}'.format(self))
return fun(self, *args, **kwargs)
return outer
@task(bind=True)
@send_email
def any_function(self):
print('inside the function')
对于以前的版本,您可以使用current_task
:
from celery import current_task
def send_email(fun):
@wraps(fun)
def outer(*args, **kwargs):
print('decorated and task is: %r' % (current_task, ))
return fun(*args, **kwargs)
@task
@send_email
def any_function():
print('inside the function')
答案 1 :(得分:5)
“之前”在视觉上看起来像“之后”。
例如,这个:
@decorator1
@decorator2
@decorator3
def func():
pass
相当于:
def func():
pass
func = decorator1(decorator2(decorator3(func)))
这意味着您必须在@send_email
后写@task
才能在@task
之前应用@task
@send_email
def any_function():
print "inside the function"
。例如:
{{1}}