【发布时间】:2019-06-10 10:36:46
【问题描述】:
假设我有一个用于执行 I/O 操作的类:
class CommunicationStack:
def __init__(self, socket):
self.socket = socket
def sync_get_data(self):
...
def sync_send_data(self):
...
async def async_get_data(self):
...
async def async_send_data(self):
...
如您所见,它具有用于相同操作的同步和异步变体,但手动编写 async_get_data 或 sync_get_data 会有点不方便。我正在寻找一种具有相同界面的智能方法,例如
def get_data(self):
... # call sync variant or return an awaitable, depending on caller type
def send_data(self):
... # call sync variant or return an awaitable, depending on caller type
所以它可以方便地使用:
stack = CommunicationStack(...)
def thread_procedure():
data = stack.get_data() # get_data returns data
async def task_procedure():
data = await stack.get_data() # get_data returns an awaitable
我相信它可以通过检查或black magic 一些棘手的方式完成:
def is_caller_coroutine():
return sys._getframe(2).f_code.co_flags & 0x380
检查调用者是协程还是函数,但是弄乱python的胆量似乎是一个糟糕的设计。
问题是:选择合适的变体的好方法是什么?或者有没有更好的方法来设计所有东西,比如使用adapters 或开发两个独立的AsyncCommunicationStack 和SyncCommunicationStack 类?
【问题讨论】:
-
David Beazley 在
curio的meta.py: seefrom_coroutine()here 中使用了他的黑魔法 的更完整版本
标签: python asynchronous python-asyncio