这是使代码可用于常规函数和异步协程的一种Python方法吗?

时间:2018-08-11 13:55:17

标签: python python-asyncio

下面是请求处理功能。处理请求意味着根据请求类型调用普通函数或协程。

当前,我有两个非常相似的代码块,它们的区别仅在于函数调用(常规调用或异步等待)上。

try:
   # either:
   result = func()
   # or:
   result = await func()
except RequestError:
   # send error reply (few lines of code)
except Exception:
   # send message about unexpected failure (few lines of code)
else:
   # send the result (also few lines of code)

自然地,我开始怀疑,如何只写一次代码(DRY)。

我可以写三个小助手(reply_errorreply_failurereply_result)或一个更大的reply(result, exception)。这是一个临时解决方案,并不是很大的改进。甚至在代码可读性方面退后一步。

或者我也可以从异步任务中调用常规函数func,但是创建任务而不进行异步操作的开销是没有道理的。

但是我可以自己运行这种特殊情况(“性能下降”)的协程,这是概念证明:

async def test():
    # not really asynchronous
    print("hello")
    return 123 

def call_coro(coro):
    try:
        coro.send(None)
    except StopIteration as err:
        return err.args[0]
    raise RuntimeError("not special case coro")

print(call_coro(test()))

结果将为(未测试):

async def handle_request(func, is_async):
    try:
        if is_async:
            result = await func()
        else:
            result = func()
    except ..... # error handling as above

及其用法:

is_async = asyncio.iscoroutinefunction(func)
if is_async:
    # create_task == ensure_future in Python < 3.7
    asyncio.create_task(handle_request(func, True))
else:
    call_coro(handle_request(func, False))

到目前为止,这是我尝试过的事情,也是我考虑取代当前代码的事情。是Pythonic还是相反?

0 个答案:

没有答案