【问题标题】:abstract method async and sync implementation in PythonPython中的抽象方法异步和同步实现
【发布时间】:2017-04-01 23:17:39
【问题描述】:

假设我有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/except。

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

谢谢!

【问题讨论】:

    标签: python asynchronous tornado mongoengine motorengine


    【解决方案1】:

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

    一般来说,您不能像在这里希望的那样在它们之间透明地切换。请记住,任何可能调用yield self.get_data() 的函数也需要用@coroutine 修饰,因此一旦系统的一部分异步,它就会开始传播。通常最好顺应这一趋势,让事情变得异步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 2011-01-09
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      相关资源
      最近更新 更多