Python中的抽象方法异步和同步实现

时间:2017-04-01 23:17:39

标签: python asynchronous tornado mongoengine motorengine

假设我BaseClass包含main_function()中的一些逻辑,这对SyncClassAsyncClass都很常见。假设这两个类具有get_data()的唯一实现,前者以同步方式进行,而后者以异步方式进行。我写了这样的东西,它似乎有效:

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()的那些方法。有更优雅的解决方案吗?我的代码有两部分与我有关:

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

我不想在这里使用try /。

另一件事是:我在@gen.coroutine中有AsyncClass@gen.coroutine中的BaseClass没有用同一功能修饰。

谢谢!

1 个答案:

答案 0 :(得分:2)

同步和异步方法具有不同的接口(这意味着异步)。 AsyncClass.get_data返回Future; SyncClass.get_data没有。如果这是一种静态类型的语言,这两种方法将无法从基类实现相同的抽象方法。当然,Python更灵活,不会以这种方式限制你,但是调用者仍然需要知道它正在处理哪种方法,或者准备通过try/except或{{ 1}}检查等(请注意,在这种情况下,try / except是危险的,因为龙卷风协程中的isinstance将接受列表和词组之类的内容)

一般情况下,您无法在此处进行透明切换,因为您希望在此处进行切换。请记住,任何可能调用yield的函数也需要用yield self.get_data()进行修饰,因此一旦系统的某个部分异步,它就会开始传播。通常最好接受这种趋势,只是让事情变得异步。