2016-12-31 7 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:クラスメソッド(@classmethod)、およびインスタンスメソッド(def calculate_price(self):):

celery = Celery(...) 

ので、私はあなたがメソッドの2つのスタイルを混合している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

のようなデコレータを使用しています。

私は本当にコードでこれを試していないが、何について:

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に結び付ける方法を理解するのではなく、一歩前進して問題を再考するべきだと思います。一般的に、セロリのタスクは、JSONを使用して簡単にシリアル化できるパラメータを受け付ける、アプリケーション内のモジュール内に存在する単なる関数でなければなりません。

関連する問題