【问题标题】:Why does Python try-except cause slowdown?为什么 Python try-except 会导致减速?
【发布时间】:2021-01-09 21:00:14
【问题描述】:

我在 python3 中为我的 RaspberryPi 编写了一个简单的应用程序。我的 rpi 进行了全新安装,并且在开始开发之前我已经完成了所有更新。此应用程序是一个显示在 LED 矩阵上的体育记分牌,并利用蓝牙游戏控制器和 evdev 模块进行输入控制。

蓝牙输入运行良好,并且 100% 响应,但如果断开连接,应用程序将崩溃,因为它无法再访问 /dev/input/event0(这是游戏手柄输入)。

我在代码中添加了 try-except 异常,这解决了崩溃问题并允许代码在游戏手柄断开连接时继续运行。这引入了两个我需要帮助的新问题。

  1. 现在大约 10% 的游戏手柄输入未注册。有时一个按钮必须按两次才能注册。

  2. 控制台中的 Ctl-C 不会停止代码执行。我将在控制台中得到以下信息:

    键盘中断: ^CException 在以下位置被忽略:del at 0x757d6588>

如果我删除游戏手柄读取的 try-except ,它将正常工作,直到游戏手柄断开连接。这是有问题的代码。

while True:
    #Gamepad read
    try:
        dev = InputDevice('/dev/input/event0')    
        gen = dev.read()
    except Exception:
        pass
    #Gamepad functions
    try:
        for ev in gen:
            if ev.type == ecodes.EV_KEY:
                if ev.value == 1:
                    if ev.code == 23:
                        if home == 0:
                            pass
                        else:
                            home-=1 
                    elif ev.code == 35:
                        home+=1 
                    elif ev.code == 34:
                        away+=1 
                    elif ev.code == 36:
                        if away==0:
                            pass
                        else:
                            away-=1
                    elif ev.code == 49:
                        stopwatch.reset()
                        start_clock == 300
                    elif ev.code == 32:
                        start_clock+=1
                    elif ev.code == 46:
                        start_clock-=1
                    elif ev.code == 33:
                        start_clock+=60
                    elif ev.code == 18:
                        start_clock-=60        
                    elif ev.code == 24:
                        away=00
                        home=00
                    elif ev.code == 37:
                        _draw_ani()
                    elif ev.code == 50:
                        if stopwatch.running:
                            stopwatch.stop()
                        else:
                            stopwatch.start()   
    except IOError:
        pass

【问题讨论】:

  • 为什么每次迭代都创建 InputDevice 对象?
  • except Exception 是个坏主意,改为捕获特定错误。

标签: python evdev


【解决方案1】:

如果引发异常,通常使用try/except 进行检查的成本特别高。This question 是一个很好的参考,可以在这方面为您提供帮助。

我认为使用if/else 条件会减少负载。为此,您应该首先检测引发异常的原因(您可以使用except Exception as error 并分析error 对象)。然后你可以用if/else检查条件。

关于您的代码,请直接使用with 而不是openingreading,如下所示:

with InputDevice('/dev/input/event0').read() as gen:
    # do stuff with gen obj

这样你就不需要手动关闭 obj 了。 现在,您的代码中的一个问题是在设备打开时尝试read

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    相关资源
    最近更新 更多