Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将类方法用作芹菜任务_Python_Django Celery - Fatal编程技术网

Python 将类方法用作芹菜任务

Python 将类方法用作芹菜任务,python,django-celery,Python,Django Celery,我试图使用类的方法作为django芹菜任务,使用@task decorator标记它。阿南德·耶哈尔(Anand Jeyahar)也提出了同样的问题。 是这样的 class A: @task def foo(self, bar): ... def main(): a = A() ... # what i need a.foo.delay(bar) # executes as celery task a.foo(bar)

我试图使用类的方法作为django芹菜任务,使用@task decorator标记它。阿南德·耶哈尔(Anand Jeyahar)也提出了同样的问题。 是这样的

class A:
    @task
    def foo(self, bar):
        ...

def main():
    a = A()
    ...
    # what i need
    a.foo.delay(bar) # executes as celery task 
    a.foo(bar) # executes locally
问题是,即使我像这样使用类实例,
a.foo.delay(bar)
它说,
foo
至少需要两个参数,这就要求
self
指针未命中

更多信息:

  • 由于继承,我无法将类转换为模块
  • 方法强烈依赖于类成员,所以我不能使它们成为静态的
  • 使用@task decorator将类标记为任务会使类本身成为任务,并且可以从
    run()
    方法执行方法,使用一些参数作为方法选择的键,但这并不是我想要的
  • 创建类的实例并将其作为
    self
    参数传递给方法会改变我执行方法的方式,而不是像芹菜一样,而是像通常的方法一样(即在测试时)
  • 我曾试图找出如何以友好的方式注册任务,例如从构造函数注册,但芹菜在工作人员之间共享代码,因此这似乎是不可能的

谢谢你的帮助

Cellery从3.0版开始就实验性地支持将方法用作任务

这方面的文档位于
芹菜.contrib.methods
中,还提到了一些您应该注意的注意事项:

注意:支持自4.0以来从芹菜中删除的
contrib.methods
,当您:

    a = A()
你可以做:

    A.foo.delay(a, param0, .., paramN)

干杯

对我来说,唯一有效的方法是芹菜。当前的应用程序,因为这将传递给方法

所以这应该是这样的:

from celery import current_app
from celery.contrib.methods import task_method

class A:
@current_app.task(filter=task_method, name='A.foo')
def foo(self, bar):
    ...

如果在不同的类中有同名的方法,则必须使用该名称。

Jeremy Satterfield提供了一个简洁明了的教程,用于编写基于类的任务,如果您想完成这些任务的话。你可以查一下

神奇之处在于基本上扩展了
芹菜.Task
类,包括
run()
方法,如下所示:

from celery import current_app
from celery.contrib.methods import task_method

class A:
@current_app.task(filter=task_method, name='A.foo')
def foo(self, bar):
    ...
来自芹菜导入任务
类自定义任务(任务):
忽略结果=真
定义初始化(self,arg):
self.arg=arg
def运行(自):
用参数(self.arg)做某事
然后按如下方式运行任务:

from celery import current_app
from celery.contrib.methods import task_method

class A:
@current_app.task(filter=task_method, name='A.foo')
def foo(self, bar):
    ...
your_arg=3
自定义任务=自定义任务()
自定义任务。延迟(您的参数)

我不确定是否需要
ignore\u result=True
部分。

我遇到了类似的情况,决定将类方法包装在一个简单的函数中,该函数将其参数重定向到类的实例,并执行此类方法:

A类:
def foo(自我,酒吧):
#这样做
a=a()
@应用程序任务
def a_包装(条形):
返回a.foo(bar)
#在导入到位的情况下,可能大小不同:
a_包装器延迟(巴)

如何执行它?同样的例子也适用于我。
a=a()
a.method(1,2)
a.method.delay(1,2)
——结果是,在未来的版本中看到这一点会很好@事实上,这已经是西芹3了,见《代码>芹菜》。方法> <代码>:好的,考虑更新你的答案,包括这一点。请注意:这看起来在10月2014号被删除了,因为它太笨了,所以我试过了,但是它不起作用。它抛出此错误-AttributeError:FileTask实例没有属性'delay',您不应该在基于类的任务中重写init@SheeshMohsin请删除init并直接在运行函数def run(self,arg)中获取arg:do_something_与_arg(arg)一起运行,如@asksol所述。自芹菜版本4以来,这已被弃用