2017-04-01 113 views
0

假設我有BaseClass其中包含main_function()中的一些邏輯,這對SyncClassAsyncClass都是通用的。假設這兩個類別具有其獨特的實現方式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 here。

另一件事是:我在AsyncClass@gen.coroutine而同樣的功能沒有在BaseClass@gen.coroutine裝飾。

謝謝!

回答

2

同步和異步方法有不同的接口(這就是異步的含義)。 AsyncClass.get_data返回Future; SyncClass.get_data沒有。如果這是一種靜態類型的語言,這兩種方法將無法從基類實現相同的抽象方法。當然,Python更靈活,並不以這種方式限制你,但是調用者仍然需要知道它正在處理的方法或準備通過try/exceptisinstance檢查等來查找(請注意,嘗試/除非在這種情況下是危險的,因爲龍捲風協同中的yield將接受像列表和字典這樣的東西)

一般而言,如果您希望在此處執行操作,則無法透明地切換它們。請記住,可能調用yield self.get_data()的任何函數也需要用@coroutine進行修飾,因此一旦系統的一部分是異步的,它就會開始傳播。通常情況下,最好接受這種趨勢,並讓事物異步。