Почему мое Python исключение не было повторно поднято? - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть функция внутри модуля, которая делает что-то вроде этого:

def some_func():

    try:
        # do some error-prone thing
        raise ValueError
        return 'calculated foo'
    except AttributeError as err:
        # handle it
        pass
    except:
        print('Some other error happened, let\'s reraise it....')
        raise
    else:
        pass
    finally:
        return 'default foo'

Затем в моей основной программе

try:
    val = some_func()
    print('val=', val)
except:
    print('In main except')
    raise
else:
    print('In main else')
    pass
finally:
    print('And we\'re done')

Мой вывод:

Произошла какая-то другая ошибка, давайте исправим ее ....

val = default foo

В главном остальном

И мы сделали

Никаких исключений не возникает.

С риском пропустить что-то очевидное, почему не перебрасывается ValueError в моей главной? Похоже, что return в моем finally в some_func() приводит к тому, что исключение не будет пересмотрено, но мне это кажется странным, и я не могу найти никаких документов об этом. Вот то, что, я думаю, должно радовать, хотелось бы понять, где я нахожусь.

  1. Я звоню some_func() в рамках моей основной программы
  2. some_func() повышает ValueError
  3. ValueError перехватывается в some_func() except, печатает «Произошла какая-то другая ошибка» и выдает ее.
  4. Вернемся к основному, я думал , ререйзируемый ValueError должен получить пойманный except, должен вывести «В основном, кроме», выполнить ререйз, и тогда само исключение должно быть отключено, что приведет к остановке программы. Но я не получаю исключений, и вместо этого я получаю предложение else.

1 Ответ

2 голосов
/ 11 февраля 2020

Это предполагаемое поведение и , описанное в документации :

Если присутствует finally, он определяет обработчик 'cleanup'. (...) Если исключение возникает в каком-либо из пунктов и не обрабатывается, исключение временно сохраняется. (...) Если предложение finally выполняет оператор return, break или continue, сохраненное исключение отбрасывается

...