将多个无限生成器对象合并为一个gen

2024-10-02 02:44:06 发布

您现在位置:Python中文网/ 问答频道 /正文

其目的是从多个游戏板读取输入并在Python中处理它。我正在使用evdev library。在

假设一个给定的设备对象dev,根据文档,使用函数dev.read_loop()可以很容易地读取游戏板发送的事件。此函数调用返回调试器告知的generator object。然后可以使用一个简单的for循环来迭代生成器。它将阻塞,直到出现新事件,然后使用for循环中使用的任何代码处理该事件。在

现在,我想用一个自定义类将来自多个游戏板的事件“流”捆绑在一起(这样做更像是为它们分配ID,跟踪断开连接等等),这就是我的问题所在。我找不到一种方法来创建这样一个生成器,它将来自所有游戏板的事件组合在一起。游戏板对象在列表中给出。在

提供的示例代码试图模拟所需的行为,但失败了。构造函数打印所有可用的设备,然后初始化它们。方法global_generator()是我解决这个问题的方法。问题是,外部for循环for device in self.__gamepads永远不会继续,因为第一个生成器是无止境的,因此总是并且只转发来自第一个控制器的事件。我试图使用itertools.chain(),但它们有相同的问题,因为第一个生成器永远不会结束。所以我想要的基本上是:“一旦这些n发生器中的一个产生一个结果,就进一步产生它(从而将它们结合起来)”。我所有的想法,比如创建队列或其他任何事情,总是因为我不能同时循环我的设备,也就是它们的生成器而停止。在

我在文档中看到了如何从多个设备读取的部分。问题是他们总是把结果打印出来,但没有展示如何以我想要的方式传递。在

import hardware.ControllerHandler as ch

controller_handler = ch.ControllerHandler()
global_generator = controller_handler.global_generator()

for event in global_generator:
    #event = ce.ControllerEvent(event)
    print(event)

^{pr2}$

因此,预期的结果是一个生成器,它返回任何底层事件,而不仅仅是第一个Gamepad中的事件。在


Tags: 对象方法代码in文档devevent游戏
1条回答
网友
1楼 · 发布于 2024-10-02 02:44:06

您可以使用aiostream库合并多个异步生成器:

    async def global_generator(self):
        loops = [device.async_read_loop() for device in self.__gamepads]
        async with aiostream.stream.merge(*loops).stream() as merged:
            async for event in merged:
                yield event

如果您不喜欢依赖aiostream,请参阅this answer,了解如何使用纯异步合并流。在

请注意,由于生成的生成器是异步的,因此需要在协同例程中使用async for对其进行迭代。在

相关问题 更多 >

    热门问题