如何编写可选地充当常规函数的 asyncio 协程? [英] How can I write asyncio coroutines that optionally act as regular functions?

查看:34
本文介绍了如何编写可选地充当常规函数的 asyncio 协程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个库,我希望最终用户能够有选择地使用它,就好像它的方法和函数不是协程一样.

例如,给定这个函数:

@asyncio.coroutinedef blah_getter():return (yield from http_client.get('http://blahblahblah'))

不想在自己的代码中使用任何异步功能的最终用户,仍然需要导入 asyncio 并运行:

<预><代码>>>>响应 = asyncio.get_event_loop().run_until_complete(blah_getter())

如果我能在 blah_getter 内部确定我是否被作为协程调用并做出相应的反应,那就太酷了.

比如:

@asyncio.coroutinedef blah_getter():if magicly_determine_if_being_yielded_from():return (yield from http_client.get('http://blahblahblah'))别的:el = asyncio.get_event_loop()返回 el.run_until_complete(http_client.get('http://blahblahblah'))

解决方案

你需要两个函数——异步协程和同步正则函数:

@asyncio.coroutinedef async_gettter():return (yield from http_client.get('http://example.com'))def sync_getter()返回 asyncio.get_event_loop().run_until_complete(async_getter())

magically_determine_if_being_yielded_from() 实际上是 event_loop.is_running() 但我强烈不建议在同一个函数中混合同步和异步代码.

I'm writing a library that I'd like end-users to be able to optionally use as if its methods and functions were not coroutines.

For example, given this function:

@asyncio.coroutine
def blah_getter():
    return (yield from http_client.get('http://blahblahblah'))

An end user who doesn't care to use any asynchronous features in their own code, still has to import asyncio and run this:

>>> response = asyncio.get_event_loop().run_until_complete(blah_getter())

It would be cool if I could, inside of blah_getter determine if I was being called as a coroutine or not and react accordingly.

So something like:

@asyncio.coroutine
def blah_getter():
    if magically_determine_if_being_yielded_from():
        return (yield from http_client.get('http://blahblahblah'))
    else:
        el = asyncio.get_event_loop()
        return el.run_until_complete(http_client.get('http://blahblahblah'))

解决方案

You need two functions -- asynchronous coroutine and synchronous regular function:

@asyncio.coroutine
def async_gettter():
    return (yield from http_client.get('http://example.com'))

def sync_getter()
    return asyncio.get_event_loop().run_until_complete(async_getter())

magically_determine_if_being_yielded_from() is actually event_loop.is_running() but I strongly don't recommend to mix sync and async code in the same function.

这篇关于如何编写可选地充当常规函数的 asyncio 协程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆