Конструкция try except удаляет мою переменную. Зачем?

Рейтинг: 2Ответов: 3Опубликовано: 18.02.2023

Вот код

ex_value = ''
try:
    2/0
except ValueError as ex_value:
    print(ex_value)
except ZeroDivisionError as ex_value:
    print(ex_value)
finally:
    print(ex_value)

Вот печать в терминале

division by zero
Traceback (most recent call last):

  File "C:\Users\Vasil\anaconda3\envs\AMZ\lib\site-packages\spyder_kernels\py3compat.py", line 356, in compat_exec
    exec(code, globals, locals)

  File "d:\onedrive\projects\chud_amaz\soft_in_dev\moduled_way_oop\code_questions\try_except_var_in_finally.py", line 15, in <module>
    print(ex_value)

NameError: name 'ex_value' is not defined

Как распечатать в finally сообщение и зачем try удаляет мою переменную ex_value.

Ответы

▲ 3Принят

Зачем try удаляет мою переменную ex_value

Как уже ответил @Danis, это происходит, потому что все объекты исключений, созданные внутри блока try-except (и также сохраненные в переменные оператором as), очищаются при завершении блоков.

Как распечатать в finally сообщение

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

try:
    2/0
except ValueError as z:
    print(ex_value := z)
except ZeroDivisionError as z:
    print(ex_value := z)
finally:
    print(ex_value)

Вывод:

division by zero
division by zero
▲ 2

Из документации:

Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs.

▲ 1

Так вы назвали ошибку именем переменной, смените обзывание ошибки другим именем:

ex_value = ''
try:
    2/0
except ValueError as ve:
    print(ex_value)
except ZeroDivisionError as zde:
    print(ex_value)
finally:
    print(ex_value)