Файл не запустився взагалі: Python не надрукував навіть перший print, а у виводі немає рядка «Traceback (most recent call last)». Що це означає?
Чому так. Шапка «Traceback» описує маршрут викликів, а при синтаксичній помилці маршруту немає — виконання не починалось. Тому обробити SyntaxError усередині цього ж файлу неможливо: try/except працює лише на живій програмі. Спокусливий варіант «виняток у першому рядку» хибний саме через відсутність шапки: вона зʼявляється завжди, коли програма встигла побігти.
Питання 2 / 8
У коді стоїть except Exception. Користувач натискає Ctrl+C. Що станеться?
Чому так. У дереві типів KeyboardInterrupt, SystemExit і GeneratorExit винесені з-під Exception навмисно — щоб звичайні обробники їх не ковтали. Саме тому except Exception безпечніший за голий except:, який дорівнює except BaseException і Ctrl+C таки проковтне.
Питання 3 / 8
У коді був одрук: flot замість float. Функція обгорнута в try з голим except:, який на будь-яку біду підставляє нуль. Що побачить користувач?
Чому так. NameError — звичайний підтип Exception, тож голий except ловить його разом з усім іншим. Помилка програміста перетворюється на охайне «не вдалося розібрати» й тихо зіпсовані числа. Це найдорожчий сорт багу: без падіння й без сліду в журналі.
Питання 4 / 8
У блоці стоять дві гілки в такому порядку: спершу except Exception, потім except ValueError. Скільки разів спрацює друга гілка?
Чому так. Гілки перебираються згори вниз, і виконується перша, яка підходить, — а не найточніша. ValueError є підтипом Exception, тож його завжди забере верхня гілка. Недосяжна гілка не є синтаксичною помилкою, тому знайти її можна тільки очима: правило — від конкретного до загального.
Питання 5 / 8
Функція має try/except ValueError/else/finally. У try стався TypeError. Що виконається?
Чому так. TypeError не є підтипом ValueError, тому гілка не спрацьовує, а else виконується лише за відсутності винятку. Але finally виконується завжди — і саме тому в ньому закривають файли й знімають блокування: прибирання відбувається навіть тоді, коли аварія летить далі.
Питання 6 / 8
Функція розібрати() кидає ValueError. Її викликає сума(), яку викликає <module>. try/except ValueError стоїть тільки в <module>. Що втрачається?
Чому так. Виняток піднімається по стеку, знищуючи кадр за кадром, доки не знайде обробника. Що нижче стоїть try, то більше роботи гине разом із кадрами. Тому лови там, де знаєш, що робити: якби try стояв усередині сума(), загинув би один кадр, а решта прайсу порахувалась би.
Питання 7 / 8
Усередині except ValueError as e ти пишеш raise ПомилкаПрайсу("рядок зіпсовано") from e. Що це дає порівняно з тим самим рядком без from e?
Чому так. Без from Python усе одно причепить первинний виняток, але назве це нейтрально: «під час обробки сталося інше». З from e сказано прямо, що це причина, і вона лягає в e.__cause__. Скорочує звіт зовсім інший запис — from None, який ланцюжок обриває.
Питання 8 / 8
Ти пишеш with suppress(FileNotFoundError): os.remove(...). Чим це чесніше за try/except: pass?
Чому так. Суть не в довжині запису, а в ширині захоплення: suppress(FileNotFoundError) ігнорує рівно один очікуваний тип, а except: pass ковтає геть усе — включно з помилками твого коду й Ctrl+C. Журналу suppress не веде: якщо подія важлива, її треба логувати явно.