JavaRush /Курси /Модуль 1: Python Core /Обробка виключень

Обробка виключень

Модуль 1: Python Core
Рівень 10 , Лекція 2
Відкрита

3.1 Перехоплення виключень

Ми б не говорили так багато про виключення, якби нам доводилося просто спостерігати за ними. Виключення — це спеціальні об'єкти, з якими може працювати ваша програма на Python. Обробка виключень — це важливий аспект програмування, який дозволяє покращити надійність та стійкість програм.

У Python для перехоплення та обробки виключень використовуються конструкції try, except, else і finally. Ці конструкції дозволяють перехоплювати помилки, що виникають під час виконання програми, та вживати відповідних заходів.

Конструкція try-except

Конструкція try-except використовується для перехоплення та обробки виключень. Блок try містить код, який може викликати виключення, а блок except містить код, який буде виконано у разі виникнення виключення.

Приклад:


try:
    result = 10 / 0
except ZeroDivisionError:
    print("Помилка: ділення на нуль.")

Якщо в коді всередині блоку try виникне виключення ZeroDivisionError, то воно буде перехоплено блоком except і виконається код з викликом методу print().

Обробка кількох виключень

Ви можете обробляти кілька типів виключень, вказавши їх в окремих блоках except.


try:
    result = int("abc")
except ZeroDivisionError:
    print("Помилка: ділення на нуль.")
except ValueError:
    print("Помилка: некоректне значення.")

Перехоплення всіх виключень

Якщо ви хочете перехоплювати всі виключення, ви можете використовувати блок except без вказівки конкретного типу виключення. Однак це не рекомендується, оскільки може ускладнити налагодження і приховати важливі помилки.


try:
    result = 10 / 0
except:
    print("Виникла помилка.")

3.2 Оператори else-finally

Крім операторів try та except, є ще два опціональних: else і finally. Зараз я розповім про них трохи детальніше.

Конструкція try-except-else

Блок else використовується для виконання коду, якщо в блоці try не виникло виключень.


try:
    result = 10 / 2
except ZeroDivisionError:
    print("Помилка: ділення на нуль.")
else:
    print(f"Результат: {result}")

Конструкція try-except-finally

Блок finally містить код, який буде виконаний незалежно від того, виникло виключення чи ні. Це корисно для звільнення ресурсів або виконання завершуючих операцій.


try:
    result = 10 / 0
except ZeroDivisionError:
    print("Помилка: ділення на нуль.")
finally:
    print("Цей блок виконується завжди.")

Повний приклад: try-except-else-finally

Приклад:


try:
    result = 10 / 2
except ZeroDivisionError:
    print("Помилка: ділення на нуль.")
else:
    print(f"Результат: {result}")
finally:
    print("Цей блок виконується завжди.")

3.3 Приклад try-except-else-finally

Давайте розглянемо якийсь великий реальний приклад. Наприклад, ми намагаємося прочитати дані з файлу на диску — що може бути простіше?


file = open("file.txt", "r")
content = file.read()
print(content)

Що може піти не так? Наприклад, все:

  • Файл може бути відсутнім. Його могли випадково видалити, не записати, або ваша програма взагалі виконується на іншому комп'ютері, де його зроду не було.
  • Помилка читання файлу. У вашої програми немає до нього доступу, оскільки він знаходиться в директорії, до якої потрібні адмінські права.
  • Інша програма зараз пише у цей файл і читати його не можна — у неї монопольний доступ до файлу.

Вам мало? Тоді не забувайте, що незалежно від того, на якому етапі сталася помилка при роботі з файлом, вам обов'язково потрібно його «закрити», щоб операційна система звільнила ресурси, виділені для роботи з цим файлом.

Так що реальний код виглядатиме приблизно так:


try:
    file = open("non_existent_file.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("Помилка: файл не знайдено.")
except IOError:
    print("Помилка: помилка вводу-виводу.")
else:
    print(content)
finally:
    if 'file' in locals() and not file.closed:
        file.close()
        print("Файл закрито.")

Ласкаво просимо в реальний світ, де вам потрібно писати код не тільки для «робочого сценарію», але і для всіх можливих сценаріїв, які можуть піти не так.

Гаразд, не буду вас лякати — це простіше, ніж здається. Потрібно просто розуміти, що таке граничні умови (corner cases) і вчасно додавати перевірку стандартних помилок. Решту сучасні фреймворки зроблять за вас.

Коментарі (11)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Alex Zotov Рівень 18
31 жовтня 2025
перевірку не проходить жодний варіант, навіть той, що надається у "Правильное решение" вже декілька задач підряд. не дуже мотивує, якщо чесно.
Матвій Рівень 28
4 серпня 2025
Не пише що треба не виводити, а повертати текст
negoda Рівень 31
13 серпня 2025
...перетворює їх у цілі числа і повертає їхню суму. Функція convert_and_sum повинна повертати суму двох перетворених чисел.
Наталья Крейц Рівень 18
26 липня 2025
Дуже сумно, що не дивлячись на правильну логіку коду все одно в деяких задачах код не проходить саме ЧЕРЕЗ ЦЕ. Хоча в умові указано " наприклад, "Некоректне значення"". То виходить, що це "наприклад" має значення "обов'язковий вивід саме цього реченння"? То нехай формулювання завдання буде чіткішою чи перевірка не буде докопуватись до виводу тексту
Mykola Рівень 21
28 лютого 2025
У задачі "Обробка вийнятків" - Мені на цьому етапі вивчення Python було неочевидним, що я маю використовувати саме return, було б не зайвим виділити або наголосити на цьому в умові задачі. Адже я написав працюючий код, тільки з print замість return. З одного боку дивно, чому не працює 🤬 , а з іншого боку отримав зайвий привід піти ще раз почитати про різницю між return та print 😇
Andriy Trubchanin Рівень 23
2 березня 2025
В задачі чітко написано, що функція має повертати повідомлення, а не виводити
Andriy Trubchanin Рівень 23
23 лютого 2025
Не зовсім зрозуміло чим принципово відрізняється ці два приклади:

try:
    result = 10 / 2
except ZeroDivisionError:
    print("Помилка: ділення на нуль.")
else:
    print(f"Результат: {result}")

try:
    result = 10 / 2
    print(f"Результат: {result}")
except ZeroDivisionError:
    print("Помилка: ділення на нуль.")
Mykola Рівень 21
28 лютого 2025
У даному, спрощеному випадку принципової різниця немає. Обидва варіанти правильні. У спрощених прикладах, для наочності, без else-блоку теж можна писати, щоб уникнути зайвих деталей, які можуть запутати початківців. Втім, коли код стає складнішим, наприклад ми маємо не один except, а декілька - втрачається читабельність коду, коли потрібно чітко відокремити успішну логіку від обробки помилок. Якщо у блоці try є більше операцій, то може бути не так очевидно, що частина коду повинна виконуватися лише за відсутності помилок.
negoda Рівень 31
13 серпня 2025
Второй вариант менее предпочтителен потому что в первом : Чёткое разделение логики — в try только то, что может вызвать конкретную ожидаемую ошибку Меньше риск замаскировать чужую ошибку — except ZeroDivisionError перехватит только деление на ноль, а не случайную ошибку в print() или других операциях Код проще сопровождать — сразу видно, где обрабатывается ошибка, а где нормальный ход программы (else) Поэтому лучше использовать первый вариант записи. Второй можно только в случае если ты точно уверен что никакой другой ошибки не возникнет, и сам код очень короткий.
Oleksandr Рівень 31
20 лютого 2025
corner cases ? Кажется этот перевод никто не проверял
negoda Рівень 31
13 серпня 2025
Знаю только edge case, тоже удивился)