簡體   English   中英

將多個無限生成器對象組合到一個生成器中

[英]Combining multiple infinite generator objects into one generator

目的是從多個游戲手柄讀取輸入並在Python中處理它。 我正在使用evdev庫

假設給定的設備對象dev ,可以根據文檔使用dev.read_loop()函數輕松讀取Gamepad發送的事件。 此函數調用返回調試器告知的generator object 然后for可以使用簡單的for循環來迭代生成器。 它會阻塞,直到發生新的事件,然后再用for循環中使用的任何代碼處理該事件。

現在,我想使用一個自定義類將事件“流”捆綁到多個游戲手柄上(這更像是為它們分配ID,跟蹤斷開連接等),這就是我的問題所在。 我找不到一種方法來創建這樣的生成器,該生成器將所有Gamepad的事件組合在一起。 游戲手柄對象在列表中給出。

提供的示例代碼嘗試模仿所需的行為,但失敗。 構造函數將打印所有可用的設備,然后對其進行初始化。 方法global_generator()是我解決此問題的方法。 問題是for device in self.__gamepads外部for循環永遠不會進行,因為第一個生成器是無限的,因此將始終且僅轉發來自第一個控制器的事件。 我嘗試使用itertools.chain()但是它們有相同的問題,因為第一個生成器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)

import evdev
from evdev import InputDevice
import asyncio


class ControllerHandler:

    def __init__(self):
        print(evdev.list_devices())
        self.__gamepads = list(map(InputDevice, evdev.list_devices()))

    @property
    def gamepads(self):
        return self.__gamepads

    @property
    def count(self):
        return len(self.__gamepads)

    async def global_generator(self):
        for device in self.__gamepads:
            async for event in device.async_read_loop():
                yield event

因此,預期結果是生成器將返回任何基礎事件,而不僅僅是第一個游戲手柄中的事件。

您可以使用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 ,請參閱此答案以獲取有關如何使用純asyncio合並流的說明。

請注意,由於生成的生成器是異步的,因此您需要在協程內部使用async for對其進行迭代。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM