Python:看不到被抛出的异常

时间:2017-08-03 15:25:14

标签: python exception exception-handling

我正在运行单元测试,我意识到抛出异常。但是,我只是不确定究竟是什么被抛出。

from pt_hil.utilities.PT_HIL_Interface_Utils.widgets import PathPicker
import unittest
import wx

class TestUM(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print 'setUpClass called'
        cls.path_picker = PathPicker()
        print 'path_picker has been declared'

    def test_PathPicker(self):
        self.assertRaises(NotImplementedError, wx.UIActionSimulator.MouseClick(self.path_picker.browse))

if __name__ == '__main__':
    unittest.main()

PathPicker类:​​

class PathPicker(Widget):

    def __init__(self, parent=None, name="PathPicker"):
        print 'hi1'
        try:
            Widget.__init__(self, name, parent)
        except Exception as e:
            print 'hello'
            return logging.error(traceback.format_exc())
        print 'hi2'

运行单元测试时得到的输出是:

setUpClass called
hi1

Process finished with exit code 1

很清楚,Widget.__init__(self, name, parent)出现了问题,但我看不出它是什么。有什么方法可以让我打印出什么异常或错误被抛出?

编辑:这是与之相关的Widget类:

class Widget(QWidget):
    def __init__(self, name, parent=None):
        print 'hey2'
        try:
            super(Widget, self).__init__()
        except BaseException as e:
            print 'hello'
            return logging.error(traceback.format_exc())
        print 'hey3'

现在它正在给我:

setUpClass called
hi1
hey2

Process finished with exit code 1

2 个答案:

答案 0 :(得分:2)

正如您所见here,python(2.x)中的最常见例外是:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      ....

因此,在您的情况下,通过捕获Exception,您会遗漏一些其他异常(罕见的异常,但可能在您的情况下发生):SystemExit,KeyboardInterrupt和GeneratorExit。 尝试将您的except子句更改为:

except BaseException as e:
通过这种方式,您将确保捕获所有异常并检测您的问题。

编辑:

但是,PyQT内部很有趣。如提到here

  

在PyQt v5.5中,未处理的Python异常将导致调用   Qt的qFatal()函数。默认情况下,这将调用abort()和   申请将终止。请注意,已安装应用程序   异常钩子仍然优先。

因此,一个未被发现的异常(可能由于C ++代码中的多种原因而发生,错误的参数......)可以静默地停止您的应用程序。 然而,最后一部分听起来很有用,如果你安装一个异常钩子,它将在静默中止之前被调用。让我们尝试添加一个异常钩子:

sys._excepthook = sys.excepthook # always save before overriding

def application_exception_hook(exctype, value, traceback):
    # Let's try to write the problem
    print "Exctype : %s, value : %s traceback : %s"%(exctype, value, traceback)
    # Call the normal Exception hook after (this will probably abort application)
    sys._excepthook(exctype, value, traceback)
    sys.exit(1)

# Do not forget to our exception hook
sys.excepthook = application_exception_hook

答案 1 :(得分:1)

我需要在脚本中添加app = QApplication(sys.argv)sys.exit(app.exec_()) class TestUM(unittest.TestCase):

以便上面的脚本看起来像:

from pt_hil.utilities.PT_HIL_Interface_Utils.widgets import PathPicker
import unittest
import wx

class TestUM(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print 'setUpClass called'
        cls.path_picker = PathPicker()
        print 'path_picker has been declared'

    def test_PathPicker(self):
        self.assertRaises(NotImplementedError, wx.UIActionSimulator.MouseClick(self.path_picker.browse))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    unittest.main()
    sys.exit(app.exec_())

请注意,这并没有解决我抛出我需要的异常的问题(因为没有异常可见)。但它确实解决了问题并且脚本会运行。谢谢!