2017-04-01 96 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进行修饰,因此一旦系统的一部分是异步的,它就会开始传播。通常情况下,最好接受这种趋势,并让事物异步。