2

我正在为我的任务队列使用Dramatiq,它提供了装饰器@dramatiq.actor来将函数装饰为任务。我尝试编写自己的装饰器来包装@dramatiq.actor装饰器,这样我就可以向适用于所有任务的装饰器添加一个默认参数@dramatiq.actor(我正在谈论的参数是priority=100)。

出于某种原因,我收到以下错误:

TypeError: foobar() takes 1 positional argument but 3 were given

如果我用它切换我的自定义@task装饰器,@dramatiq.actor那么我猜我的自定义装饰器不正确,但我无法发现我的错误。

装饰器.py

def task(func=None, **kwargs):    
    def decorator(func):
        @wraps(func)
        @dramatiq.actor(priority=100, **kwargs)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)

        return wrapper

    if func is None:
        return decorator

    return decorator(func)

任务.py

@task
def foobar(entry_pk):
    ...

视图.py

foobar.send_with_options(args=(entry.pk,))
4

2 回答 2

3

使用起来会容易得多functools.partial

from functools import partial

task = partial(dramatiq.actor, priority=100)

@task
def foobar(*args, **kwargs):
    ...

这使您可以抢先向函数添加参数,而无需实际调用它。

于 2020-01-07T14:15:20.320 回答
0

另一种方法是子类化Dramatiq该类并覆盖该actor方法。这种方法加上这里描述的其他一些技巧 - https://blog.narrativ.com/converting-celery-to-dramatiq-a-py3-war-story-23df217b426

于 2020-01-29T19:50:26.170 回答