Python 芹菜:如何忽略和弦或锁链中的任务结果?

Python 芹菜:如何忽略和弦或锁链中的任务结果?,python,asynchronous,task,celery,Python,Asynchronous,Task,Celery,我在用芹菜,我有几个任务需要按顺序执行 例如,我有一个任务: @celery.task def tprint(word): print word 我想这样做: >>> chain(tprint.s('a') | tprint.s('b'))() @celery.task def tprint(result, word): print word 然后我得到TypeError:tprint()正好接受1个参数(给定2个) 和chord一样,在这种情况下,我需要

我在用芹菜,我有几个任务需要按顺序执行

例如,我有一个任务:

@celery.task
def tprint(word):
    print word
我想这样做:

>>> chain(tprint.s('a') | tprint.s('b'))()
@celery.task
def tprint(result, word):
    print word
然后我得到
TypeError:tprint()正好接受1个参数(给定2个)

和chord一样,在这种情况下,我需要在一组任务之后执行一个任务:

>>> chord([tprint.s('a'), tprint.s('b')])(tprint.s('c'))
那么如何应对这种情况呢?我不在乎每个任务的结果,但它们需要按顺序执行


添加第二个参数无效:

@celery.task
def tprint(word, ignore=None):
    print word

>>> chain(tprint.s('a', 0) | tprint.s('b'))()

这将打印出“a”和“无”。

您可以尝试这样做。 函数tprint可以有两个参数,而不是一个参数

def tprint(word, x=None):
    print word
然后


最后,找到一个解决办法,一个连锁装饰师将完成这项工作

我不知道西芹到底是怎么做到的,但西芹似乎强制将前一个任务的结果绑定到下一个任务的第一个参数

下面是一个例子:

def chain_deco(func):

    @functools.wraps(func)
    def wrapper(chain=None, *args, **kwargs):
        if chain is False:
            return False

        func(*args, **kwargs)
        return True

    return wrapper


@celery.task
@chain_deco
def hello(word):
    print "hello %s" % word
现在,这将给出正确的输出

>>> (hello.s(word='a') | hello.s(word='b'))()

并且decorator还提供了在中间停止一个链的能力(使后面的级联失败)


同样的机制也应该适用于
chord

有一个内置功能可以忽略链接和其他不可变子任务的结果。可以使用.si()快捷方式而不是.s()或.subtask(immutable=True)


这里有更多详细信息:

已经发布了一个可能的解决方案,但我想补充进一步的说明和一个替代解决方案(在某些情况下是一个更好的解决方案)

您看到的错误表明任务的签名需要考虑第二个参数,这是由于在
中调用任务时,芹菜会自动将每个任务的
结果
作为以下任务的第一个参数

任务可以链接在一起,这实际上意味着添加回调任务:

链接的任务将以其父任务的结果作为第一个参数应用

因此,在您的情况下,您可以这样重写您的任务:

>>> chain(tprint.s('a') | tprint.s('b'))()
@celery.task
def tprint(result, word):
    print word
如果你不打算对结果做任何事情,你也可以通过以下方式忽略它:

这样你就不必更改你的任务签名了


很抱歉,最后一点需要进一步研究。

我建议使用
*ignore,**kwignore
参数来涵盖此解决方案无法概括的任何组合。如果他需要链接3个函数,您会添加第3个参数来忽略吗?您正在弄乱函数的名称空间和整体语义。.si()建议是正确的答案。芹菜和弦头使用一个组,该组并行执行,因此,如果顺序是相关的,则不应使用它!我读了文档,但仍然不理解术语,如果你不介意分享,不变性到底应该怎么做?他们似乎滥用了这个术语,但这个选项背后的想法很简单。它将函数标记为不希望从传递给其参数的链式计算中得到结果的函数。
@celery.task
def tprint(result, word):
    print word
@celery.task(ignore_result=True)