Python的尝试-除非无法正常工作

时间:2018-07-05 11:32:08

标签: multithreading python-3.x exception

我在理解异常如何在Python中正常工作时遇到了麻烦。

在下面的代码中,someClass被初始化,并且run_engine()方法被调用。 run_engine()方法产生各种线程,这些线程之一是“数据源”线程。数据源线程在数据库中查询一组特定的数据,该数据库将依次开始流式传输(子发布机制)查询的数据集。当将completedata集传输到我的Python应用程序时,数据库将关闭与数据源线程的连接,以指示流已结束并且可能发生其他操作。这就是麻烦的开始。

在下面的_fetch_data()方法中,我捕获了QReaderException(在数据库断开连接时抛出的那个),并抛出了一个自定义的(ServiceExitException),以便执行一些操作。主线程中的最终操作。

由于某种原因,它会同时显示两个异常的堆栈跟踪信息(因此QReaderException似乎已被捕获,但不会默默地消失。

为什么会这样?它与我的应用程序的线程性质有关吗?

谢谢!

# This method belongs to the data source thread
def _fetch_data(self):
    while not self.stopped():
        try:
            message = self.connections[self.port].receive(data_only=False, raw=False)  # retrieve entire message
            if message.type != MessageType.ASYNC:
                raise UnexpectedMessageTypeException('Unexpected message, expected message of type: ASYNC')
            if isinstance(message.data, list):
                return message

        except (QReaderException, UnexpectedMessageTypeException) as e:
            # this block seems to be executed
            raise ServiceExitException()


if __name__ == '__main__':
    someClass = SomeClass()

    try:
        someClass.run_engine()
        while True:
            time.sleep(0.5)

    except ServiceExitException as e:
        someClass.stop_engine()
        someClass.join()
        someClass.store_data()
        sys.exit(0)

1 个答案:

答案 0 :(得分:1)

说类似的话之间应该有一段

  

在处理上述异常期间,发生了另一个异常:

您可以说Python直到except块结束才将第一个异常视为已处理。因此,它们都被视为未处理,并且回溯被合并为一个。

如果您使用

,可能会变得更加清晰
raise ServiceExitException() from e

然后,回溯之间的消息变为

  

上述异常是以下异常的直接原因:

但是,使用AFAIK可以进行这种异常重定向。我猜最简单的事情就是放弃自定义ServiceExitException,而只except:主代码中的所有内容。甚至更好的方法是使用try: .. finally: ..构造,该构造避免了pylint之类的工具令人讨厌的提示,即您不应该执行广泛的全能except