13

我有一个看起来像这样的任务

from mybasetask_module import MyBaseTask

@task(base=MyBaseTask)
@my_custom_decorator 
def my_task(*args, **kwargs):
    pass

我的基本任务看起来像这样

from celery import task, Task

class MyBaseTask(Task):
    abstract = True
    default_retry_delay = 10 
    max_retries = 3 
    acks_late = True

我遇到的问题是芹菜工人正在使用名称注册任务

'mybasetask_module.__inner'

当我从任务中删除 @my_custom_decorator 或者像这样为任务提供显式名称时,任务注册良好(即包+模块+函数)

from mybasetask_module import MyBaseTask

@task(base=MyBaseTask, name='an_explicit_task_name')
@my_custom_decorator 
def my_task(*args, **kwargs):
    pass

这种行为是预期的吗?当我有多个装饰器但没有明确的任务名称时,我是否需要做一些事情以便在第一种情况下使用默认的自动注册名称注册我的任务?

谢谢,

4

1 回答 1

29

使用functools.wraps()装饰器确保返回的包装器my_custom_decorator具有正确的名称:

from functools import wraps

def my_custom_decorator(func):
    @wraps(func)
    def __inner():
        return func()
    return __inner

任务名称取自task装饰器包装的函数调用,但通过在两者之间插入装饰器,您task可以__inner改为使用包装函数。装饰器将functools.wraps()所有必要的元数据复制func到包装器中,以便task()获取正确的名称。

于 2012-11-21T11:51:42.643 回答