从现有装饰器创建新装饰器

2024-05-10 01:01:36 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

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

如果我用@dramatiq.actor切换我的自定义@task装饰器,它会工作,所以我想我的自定义装饰器是不正确的,但我无法发现我的错误

decorators.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)

tasks.py

@task
def foobar(entry_pk):
    ...

views.py

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

Tags: pytask参数returndef错误args装饰
2条回答

使用^{}会容易得多:

from functools import partial

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

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

这允许您在不实际调用函数的情况下,先发制人地向函数添加参数

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

相关问题 更多 >