【问题标题】:Problems passing argument to python function with decorator使用装饰器将参数传递给 python 函数的问题
【发布时间】:2013-07-09 17:15:00
【问题描述】:

我有以下代码,导致此错误:

TypeError('smallTask() takes exactly 1 argument (2 given)',)

@task
def master():
    count = 0
    obj = { 'var1':'val1', 'var2':'val2' }

    while count < 10:
        subtask('smallTask',obj).apply_async()
        count += 1

@task(name='smallTask')
def smallTask(obj):
    print obj

将字典传递给函数,我想我需要使用 **kwargs 但如果这样做,我会收到错误,即该函数不接受参数但已提供 2。

我认为这里的问题是装饰器(对此有基本的了解,但不足以解决问题)或 Celery 中的 subtask 函数。

我没有足够的 python 知识来真正继续..谁能告诉我正在发生的事情以及如何将 smallTask​​ 函数传递给字典?

【问题讨论】:

    标签: python celery decorator python-decorators


    【解决方案1】:

    您需要在args关键字参数中传递子任务的参数,该参数必须是根据celery.subtask() documentation的元组:

    subtask('smallTask', args=(obj,)).apply_async()
    

    或使用Task.subtask() 方法在您的smallTask 任务,但再次将参数作为元组传递:

    smallTask.subtask((obj,)).apply_async()
    

    或者,使用带有 Task.s() method 的星形参数:

    smallTask.s(obj).apply_async()
    

    你自己链接的subtasks documentation 在示例中使用元组;参数和关键字参数是 Celery 必须为您存储的两条数据,直到它可以运行该任务,然后它将为您应用这些参数和关键字参数。

    但celery.subtask() 函数不仅为您的任务接受参数和关键字参数;它还需要其他选项。为了在您的任务中使用任意参数(位置或关键字),和支持未传递给您的任务的其他参数,函数签名别无选择,只能接受位置参数作为显式元组,关键字参数作为显式字典。

    Task.s() 方法不接受除任务本身接受的参数之外的任何参数,因此它支持传递参数,就像您直接调用任务一样。在内部,它使用包罗万象的参数:Task.s(*args, **kwarg),并将捕获的参数作为元组和字典传递给Task.subtask()。

    【讨论】:

    • 好的,这绝对有效并且乐于接受,但在这一点上,它也可能是巫术。你介意再详细说明一下吗?我可以研究关键字参数,但为什么 obj 是一个元组?谢谢,
    • 谢谢,这很有帮助。这更像是我对 python 的理解不够,无法使文档有用。需要阅读位置和关键字参数。非常感谢您花时间回答。谢谢!
    • 如果我有两个子任务的声明像my_first_task(arg11, arg12, arg13=False, arg14=True) 和my_second_task(arg21, arg22, arg23=False, arg24=True)。那么我们在调用group([my_first_task.s(...), my_second_task.s(...)]) 时如何向它们传递参数呢?谢谢!
    • @KevinGhaboosi: Task.s() 可以像直接调用任务一样调用。所以group([my_first_task.s(value_for_arg11, value_for_arg12, arg13=perhaps_value_for_arg13), ...]).
    猜你喜欢
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 2016-01-30
    • 2014-11-17
    • 2016-02-14
    • 2021-11-15
    相关资源
    最近更新 更多