2016-12-31 41 views
0

我有一些基類,如:芹菜任務使用超級

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() 

所以,我的問題是與代碼的最後一行,它提出: TypeError: super(type, obj): obj must be an instance or subtype of type

我試圖刪除bind=True和玩一點它,但沒有結果。任何想法如何解決這個問題?

UPDATE: 其中

celery = Celery(...) 

所以,我使用的裝飾像app.task

+0

通常可以看到任務裝飾器與函數一起使用,而不是方法。我並不是說它不能完成,但很少見。討論如何將任務行爲放在類中的資源很多(例如https://blog.balthazar-rouberol.com/celery-best-practices),但任務裝飾器仍然適用於普通函數。也許你可以用這種方式簡化你的設計。相關:http://stackoverflow.com/questions/9250317/using-class-methods-as-celery-tasks – FMc

+0

@FMc,我已經讀過這兩個主題。在那裏沒有這種情況。我真的需要基礎類,並在子類中運行一些方法作爲任務芹菜。所以我需要以某種方式解決我的問題,而不需要更改架構 – smart

+0

是的,在這些主題中或者在任何Celery文檔中都沒有像您這樣的情況,因爲我不認爲Celery支持使用任務裝飾器一個方法。你需要使用一個功能。特別是,在我提供的StackOverflow鏈接中,請注意來自Hamy的評論。它看起來像你目前的設計根本無法工作。 – FMc

回答

0

你是混合了兩種風格的方法:類方法(@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輕鬆序列化的參數。