Python中的抽象方法异步和同步实现
问题描述:
假设我有BaseClass
其中包含main_function()
中的一些逻辑,这对SyncClass
和AsyncClass
都是通用的。假设这两个类别具有其独特的实现方式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
装饰。
谢谢!
答
同步和异步方法有不同的接口(这就是异步的含义)。 AsyncClass.get_data
返回Future
; SyncClass.get_data
没有。如果这是一种静态类型的语言,这两种方法将无法从基类实现相同的抽象方法。当然,Python更灵活,并不以这种方式限制你,但是调用者仍然需要知道它正在处理的方法或准备通过try/except
或isinstance
检查等来查找(请注意,尝试/除非在这种情况下是危险的,因为龙卷风协同中的yield
将接受像列表和字典这样的东西)
一般而言,如果您希望在此处执行操作,则无法透明地切换它们。请记住,可能调用yield self.get_data()
的任何函数也需要用@coroutine
进行修饰,因此一旦系统的一部分是异步的,它就会开始传播。通常情况下,最好接受这种趋势,并让事物异步。