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



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

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

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

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

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,))

使用functools.partial会容易得多:

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

相关内容

  • 没有找到相关文章