简体   繁体   English

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

[英]abstract method async and sync implementation in Python

Let's say I have BaseClass which contains some logic in main_function() which is common for both SyncClass and AsyncClass . 假设我有BaseClass ,它在main_function()包含一些逻辑,这对于SyncClassAsyncClass都是通用的。 Let's say those 2 classes have their unique implementation of get_data() and the former gets in synchronous manner, while the latter in asynchronous manner. 假设这两个类具有其get_data()的唯一实现,并且前者以同步方式获取,而后者以异步方式获取。 I have written something like this and it seems to work: 我写了这样的东西,它似乎起作用:

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)

I used this code as a workaround, because I already had those methods for get_data() implemented that way. 我将这段代码用作解决方法,因为我已经以这种方式实现了get_data()的那些方法。 Is there some more elegant solution? 还有更优雅的解决方案吗? There are 2 parts of my code that concern me: 我的代码有两部分与我有关:

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

I would prefer not to use try/except here. 我不希望在这里不使用try / except。

The other thing is: I have @gen.coroutine in the AsyncClass while the same function isn't decorated with @gen.coroutine in the BaseClass . 另一件事是:我有@gen.coroutineAsyncClass而同样的功能不与装饰@gen.coroutineBaseClass

Thank you! 谢谢!

Synchronous and asynchronous methods have different interfaces (that's what it means to be asynchronous). 同步和异步方法具有不同的接口(这就是异步的含义)。 AsyncClass.get_data returns a Future ; AsyncClass.get_data返回一个Future SyncClass.get_data does not. SyncClass.get_data没有。 If this were in a statically-typed language, these two methods would not be able to implement the same abstract method from the base class. 如果这是静态类型的语言,则这两个方法将无法从基类实现相同的抽象方法。 Of course, Python is more flexible and does not restrict you in this way, but the caller still needs to either know which kind of method it's dealing with or be prepared to find out via try/except or isinstance checks, etc. (note that try/except is dangerous in this case, because yield in a tornado coroutine will accept things like lists and dicts) 当然,Python更加灵活,并且不以这种方式限制您,但是调用者仍然需要知道它正在处理哪种方法,或者准备通过try/exceptisinstance检查等方法来查找它(请注意,在这种情况下,try / except很危险,因为龙卷风协程中的yield会接受列表和字典之类的东西)

In general, you cannot transparently switch between them as you're hoping to do here. 通常,您无法像在此处希望的那样在它们之间透明地切换。 Remember that any function that may call yield self.get_data() also needs to be decorated with @coroutine , so once one part of your system is asynchronous, it starts to spread. 请记住,任何可能调用yield self.get_data()函数也都需要用@coroutine装饰,因此一旦系统的一部分异步,它就会开始传播。 It's usually best to embrace this trend and just make things asynchronous. 通常最好是顺应这种趋势,并使事情变得异步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM