2017-12-05 17 views
1

私はPythonのデコレータに少し問題があります。私はデコレータにfuncとして存続しているように見える最初の呼び出し方の機能、いくつかの理由Pythonのカスタムデコレータがセロリのタスクで動作しない

def decorated(func): 
    def call_and_update(*args, **kwargs): 
     # do some stuff here 
     output = func(*args, **kwargs) 
     # do more stuff here 
     return output 
    return call_and_update 

@celery.task 
@decorated 
def testA(): 
    return "Test A" 

@celery.task 
@decorated 
def testB(): 
    return "Test B" 

:私はそうのように設定したシナリオを持っています。例えばので

、私はシェルを起動して実行する場合:

>>> testA() 
Test A 
>>> testB() 
Test A 

かを、私はシェルを再起動し、第二の試験で始める場合:

>>> testB() 
Test B 
>>>> testA() 
Test B 

私はthis question with a similar issueを見つけましたが、いくつかの答えは、代わりにタスクメソッドの拡張クラスを使用しています。

私が具体的にデコレータと関数でこれを行うには、それを動作させるためのトリックはありますか?

@celery.taskデコレータなしの場合、これらの機能は正常に機能します。具体的には、問題を引き起こしている2つのデコレータの組み合わせです。

ありがとうございます!

+0

セロリタスクデコレータを使用している場合にのみこの現象が発生していますか? –

+0

@ juanpa.arrivillaga correct。 celery.taskデコレータなしでは、関数は正常に動作します。 (私は質問にこれを書き留めます) – CaptainPlanet

+0

これは重複しています。 TLDR: 'functools.wraps()'を使用して、セロリタスクが正しい関数名を記録できるようにします(そうでなければ、あなたのタスクの名前は 'call_and_update'です)。 –

答えて

1

それぞれのタスクは、ラッパー機能の名前を使用していないので、一意の名前celery docsを持つ必要があります。

@celery.task(name='test-A') 
@decorated 
def testA(): 
    return 'test A' 

@celery.task(name='test-B') 
@decorated 
def testB(): 
    return 'test B' 
+0

うん、それはそれをやった!これについて忘れてしまったのは、自然にデフォルトの関数名になっているようですが、関数が余分な '@ decorated'デコレータに囲まれていると、そのデコレータ関数名の代わりにデコレータのデフォルト値が使われていました。ありがとう! – CaptainPlanet

+1

@CaptainPlanet: ''関​​数 ''の中で['functools.wraps'](https://docs.python.org/3/library/functools.html#functools.wraps)を使うこともできます。これは、あなたの装飾された機能を、その名前を更新することによって元のように "見える"ようにします。 – Blender

関連する問題