python - 如何集成 Python mido 和 asyncio?
问题描述
我有一个通过 MIDI 进行文件 I/O 的设备。我有一个使用 Mido 下载文件的脚本,但它是一堆全局变量。我想整理它以正确使用 asyncio 但我不确定如何集成 mido 回调。我认为文档说我应该使用 Future 对象,但我不确定 mido 回调函数如何获取该对象。
解决方案
mido
提供了一个基于回调的API,它将从不同的线程调用回调。您的回调实现可以通过调用与 asyncio 进行通信loop.call_soon_threadsafe
。请注意,您将无法仅设置 a 的值,Future
因为回调将被多次调用,而 future 只能设置一次 - 它用于一次性计算。
多次调用回调的常见模式是将事件推送到 asyncio队列并在 asyncio 代码中从中弹出内容。通过将队列公开为异步迭代器,这可以变得更加方便。此功能使该过程自动化:
def make_stream():
loop = asyncio.get_event_loop()
queue = asyncio.Queue()
def callback(message):
loop.call_soon_threadsafe(queue.put_nowait, message)
async def stream():
while True:
yield await queue.get()
return callback, stream()
make_stream
返回两个对象:
- 一个回调,您可以将其传递给
mido.open_input()
- 一个流,您可以对其进行迭代
async for
以获取新消息
每当 mido 在其后台线程中调用回调时,您async for
在流上迭代的 asyncio 循环将唤醒一个新项目。实际上,make_stream
将线程回调转换为异步迭代器。例如(未经测试):
async def print_messages():
# create a callback/stream pair and pass callback to mido
cb, stream = make_stream()
mido.open_input(callback=cb)
# print messages as they come just by reading from stream
async for message in stream:
print(message)
推荐阅读
- pandas - pyspark 中的 defaultdict 实现
- javascript - 通过Id nodejs获取多个元素
- sql - 我有这个错误 ORA-00917:缺少逗号?
- reactjs - 在 apollo 中取消对 refetch 的查询
- javascript - 如何将变量从服务器js文件传递到另一个
- batch-file - 获取电脑扩展槽的卡信息
- git - .gitignore 错过了 NetBeans 11.x 中的尾随新行
- python - 如果在 __init__ 中未使用,则类 ser 端口为无
- php - 如何对查询的行列值进行排序,然后在 HTML 上显示它们?
- conan - cmake_find_package 和 cmake INTERFACE 包