Вы смешиваете два стиля методов: методы класса (@classmethod
) и методы экземпляра (def calculate_price(self):
).
Я действительно не пробовал это в коде, но как насчет:
class Auto(object):
_year = None
_base_price = None
@classmethod
def calculate_price(cls):
return cls._base_price + 5000 * (2016 - cls._year)
class BMW(Auto):
_year = 2015
_base_price = 40000
@celery.task(filter=task_method, name='queue_name', base=basetask(), bind=True)
@classmethod
def calculate_price(cls, task_self):
super(BMW, cls).calculate_price()
Таким образом, декоратор @classmethod
сначала применяется к def calculate_price(...):
, а затем @celery.task
применяется к методу класса.
Если вам нужно, чтобы calculate_price()
был методом экземпляра, тогда сигнатура может быть def calculate_price(self, task_self):
, но вам нужно применить декоратор, когда у вас уже есть экземпляр, например:
my_car = BMW()
celery.task(my_car.calculate_price)
Когда вы обращаетесь к методу с помощью instance<dot>method
, вы не получаете написанную вами функцию, вы получаете дескриптор метода, который при вызове позаботится о заполнении первого аргумента (self
), оставив вам заполнение остальных аргументов. В данном случае это только аргумент task_self
, и об этом позаботится декоратор @celery.task
.
В любом случае, я думаю, вам следует отступить и переосмыслить свою проблему более общим образом, вместо того, чтобы выяснять, как связать методы класса/экземпляра с Celery. В общем, задачи Celery должны быть просто функциями, живущими в модуле внутри вашего приложения, которые принимают параметры, которые можно легко сериализовать с помощью JSON.
person
Armando Pérez Marqués
schedule
06.03.2017
app.task
в качестве предложенной документации для celery 4.X. Вот почему я могу быть уверен, что он поддерживает на данный момент - person smart   schedule 02.01.2017