Попытка Python - кроме не работает, как ожидалось - PullRequest
0 голосов
/ 05 июля 2018

У меня проблемы с пониманием того, как исключения работают именно в Python.

В приведенном ниже коде инициализируется someClass и вызывается метод run_engine(). Метод run_engine() порождает различные потоки, и один из этих потоков является потоком «источника данных». Поток источника данных запрашивает у базы данных определенный набор данных, и база данных, в свою очередь, начинает потоковую передачу (механизм подпабликации) запрашиваемого набора данных. Когда набор завершенных данных будет передан в мое приложение 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 голосов
/ 05 июля 2018

Должна быть грань между словами что-то вроде

Во время обработки вышеуказанного исключения произошло другое исключение:

Можно сказать, что Python не считает первое исключение обработанным до тех пор, пока не будет завершен блок исключений. Поэтому они оба считаются необработанными, а трассировки объединяются в один.

Может быть, станет немного понятнее, если вы используете

raise ServiceExitException() from e

Тогда сообщение между трассировками становится

Вышеуказанное исключение было прямой причиной следующего исключения:

Но AFAIK, это так далеко, как вы можете пойти с таким перенаправлением исключений. Я думаю, что проще всего было бы просто оставить пользовательский ServiceExitException и просто except: все в вашем основном коде. Или, что еще лучше, используйте конструкцию try: .. finally: .., которая позволяет избежать раздражающих намеков от таких инструментов, как pylint, что вам не следует делать широкие всеохватывающие except s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...