Python 将类方法用作芹菜任务
我试图使用类的方法作为django芹菜任务,使用@task decorator标记它。阿南德·耶哈尔(Anand Jeyahar)也提出了同样的问题。 是这样的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)
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以来,这已被弃用