引发异常和自动引发异常之间的区别

时间:2014-06-18 00:36:43

标签: python wxpython

目前使用wxPython框架,我的代码如下所示:

事件绑定:

self.frequency_grid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.on_cell_changed)

处理已更改单元格的函数:

def on_cell_changed(self, event):
    self.current_grid = event.GetEventObject()
    try:
        new_value= self.get_cell_value()
        if new_value < 0:
            raise AttributeError
        #allow the cell to update
    except AttributeError:
        event.Veto()
        wx.MessageBox(_("Positive values only."), "", wx.OK|wx.ICON_WARNING)
    except:
        wx.MessageBox(_("Invalid value for cell."), "", wx.OK|wx.ICON_WARNING)
        event.Veto()

函数get_cell_value()从当前单元格中读取值,并使用int()将其转换为整数。如果用户输入的字符类似于&#39; a&#39;进入单元格,显然这个函数失败并引发异常。在这种情况下,消息框会告诉用户单元格的值无效。这就是我所说的自动引发的异常,并执行了最后的异常块。

在负值的情况下,我手动引发一个AttributeError(只是想看到与ValueError不同的东西,这是当用户输入字符时发生的事情)。 但是,在这种情况下,wxPython会将EVT_GRID_CELL_CHANGE事件发送两次,因此手动引发的异常必须有所不同。

我已经在http://trac.wxwidgets.org/ticket/16333分别提出了关于重复事件的故障单,但只是试图了解第一种情况与第二种情况相比如何使wxPython发送2个事件。

3 个答案:

答案 0 :(得分:0)

如果你真的想要捕获任何可能的错误(甚至是系统内存或其他任何不相关的错误),请不要使用except:

为了让你的代码看起来更好,我建议使用try ... except block将值转换为int,然后检查负值。

try:
    value = int(text)
except:
    return MessageBox('Enter digit')
if value < 0:
    return MessageBox('Enter positive digit')

答案 1 :(得分:0)

例外情况没有区别,但您正在以不同的方式处理它们,代码中的不同位置。

我怀疑这是导致额外事件的veto()调用。但为什么不在一个地方验证输入?你的get_cell_value()函数应该确保它是一个整数&gt; 0。

此外,这个结构既是循环事件的配方,也是令人痛苦的烦人UI。人们应该能够制作一个拼写错误并返回并更正它,而不会出现恼人的对话框。

可能提供问题的指示器,例如将单元格背景设置为红色,但只有在用户尝试继续下一步后才进入对话框路径。

答案 2 :(得分:0)

经过一些跟踪后,我发现创建MessageBox会导致EVT_GRID_CELL_CHANGING事件发生,然后导致EVT_GRID_CELL_CHANGED事件发生,这就是我看到重复事件的原因。 我在字符输入期间没有看到重复事件的原因是因为如果int()转换无效,则在EVT_GRID_CELL_CHANGING的事件处理程序中调用了Veto()因为我的该事件的处理程序获取了网格输入并尝试转换它。

总之,Python异常处理没有区别,但是,应该实现更好的wxPython演示,以防止演示过程中出现重复的消息框,并向其他用户展示如何更好地使用网格机制。