You are mixing two styles of methods: Class methods (@classmethod
), and instance methods (def calculate_price(self):
).
I haven't really tried this in code, but what about:
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()
So the @classmethod
decorator is applied first to def calculate_price(...):
, and then the @celery.task
is applied to the class method.
If you do need calculate_price()
to be an instance method, then the signature could be def calculate_price(self, task_self):
but you need to apply the decorator when you already have an instance, like:
my_car = BMW()
celery.task(my_car.calculate_price)
When you access a method using instance<dot>method
you don't get the function you wrote, you get a method descriptor that when called, it will take care of fill out the first argument (self
) leaving to you filling the remaining arguments. In this case, is only the task_self
argument, and the @celery.task
decorator will take care of that one.
In any case, I think you should step back, and rethink your problem in a more generic way instead of figuring out how to tie class/instance methods to Celery. In general, Celery tasks should be just functions living in a module inside your application, which accept parameters that can be easily serialized using JSON.