2017-04-01 3 views
0

BaseClassには、SyncClassAsyncClassの両方に共通するmain_function()のロジックが含まれています。その2つのクラスがget_data()という独自の実装を持ち、前者が同期的に取得され、後者が非同期的に取得されるとしましょう。私はこのような何かを書かれているし、動作しているようです:抽象メソッドPythonでの非同期と同期の実装

class BaseClass: 
    def get_data(): 
     pass 

    @gen.coroutine 
    def main_function(): 
     # some logic 
     try: 
      data = yield self.get_data() 
     except: 
      data = self.get_data() 
     # some more logic 

class SyncClass(BaseClass): 
    def get_data(): 
     //makes sync call to Mongo and gets data (using Mongoengine) 

class AsyncClass(BaseClass): 
    @gen.coroutine 
    def get_data(): 
     //makes async call to Mongo and gets data (using Motorengine) 

私はすでにget_dataため、これらのメソッドは、()そのように実装されていたので、私は、回避策としてこのコードを使用していました。もっと洗練されたソリューションがありますか?私に関係する私のコードの2つの部分があります:

try: 
    data = yield self.get_data() 
except: 
    data = self.get_data() 

ここではtry/exceptを使用したくないです。

他の事は次のとおりです。同じ機能がBaseClass@gen.coroutineで飾られていない間、私はAsyncClass@gen.coroutineを持っています。

ありがとうございました!

答えて

2

同期メソッドと非同期メソッドには異なるインターフェイスがあります(つまり、非同期であることを意味します)。 AsyncClass.get_dataFutureを返します。 SyncClass.get_dataはありません。これが静的型言語である場合、これらの2つのメソッドは基本クラスと同じ抽象メソッドを実装できません。もちろん、Pythonは柔軟性があり、このようにあなたを制限するものではありませんが、呼び出し側はどのメソッドを扱っているのか、またはtry/exceptisinstanceのチェックなどで調べる準備が必要です(try/

一般に、あなたがここでやりたいと思っているように、それらの間を透過的に切り替えることはできません。この場合は危険です。ただし、この場合は危険です。竜巻のコルーチン内のyieldはリストやディクテーションのようなものを受け入れます。 yield self.get_data()を呼び出す関数も@coroutineで修飾する必要があるので、システムの1つの部分が非同期になると、拡散が始まります。通常、この傾向を受け入れ、物事を非同期にするのが最善です。