I have some base class like:
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)
def calculate_price(self):
super(BMW, self).calculate_price()
So, my problem is with the last line of code, it raises:
TypeError: super(type, obj): obj must be an instance or subtype of type
I was trying to remove bind=True
and play a little with it, but with no results. Any ideas how to fix this issue?
UPDATE: where
celery = Celery(...)
so, I'm using decorator like app.task
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:
So the
@classmethod
decorator is applied first todef 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 bedef calculate_price(self, task_self):
but you need to apply the decorator when you already have an instance, like: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 thetask_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.