В Python все исключения наследуются от класса BaseException. Это означает, что каждое исключение в Python является экземпляром BaseException или одного из его подклассов.
Класс BaseException является вершиной иерархии исключений. Он предоставляет некоторые общие методы, которые могут использовать все исключения, такие как __str__ и __repr__. Однако не рекомендуется использовать BaseException напрямую в вашем коде, так как он слишком общий и может перехватывать любой тип исключения. Вместо этого следует использовать более специфичные классы исключений, которые являются подклассами BaseException. Python предоставляет ряд встроенных классов исключений, которые вы можете использовать, а также вы можете создавать свои собственные пользовательские классы:
The hierarchy of built-in exception classes in Python (from the official Python docs).
Это означает, что FileNotFoundError является подклассом OSError, который, в свою очередь, является подклассом класса Exception, который наследуется от BaseException.
Соблюдение иерархии исключений
При использовании нескольких операторов except важно соблюдать иерархию исключений в Python. Это означает, что если вы обрабатываете базовый класс исключений, такой как Exception, вы должны обрабатывать более конкретные исключения перед ним. Если вы напишете оператор except для более специфичного класса после базового класса, этот блок не будет выполнен:
try:
# some code that may raise an exception
except ValueError:
# handle the ValueError
except Exception:
# handle any other exception
В этом примере сначала обрабатывается исключение ValueError. Если код вызывает любое другое исключение, наследующееся от Exception, будет выполнен код во втором блоке except. Однако не рекомендуется перехватывать Exception напрямую, так как это слишком общее и может перехватить любой тип исключения. Лучше обрабатывать более специфичные исключения, когда это возможно:
Если код в блоке try вызывает TypeError или ValueError, будет выполнен соответствующий блок except. Если код вызывает любое другое исключение, наследованное от Exception, будет выполнен код в третьем блоке except.
Если мы разместим базовое исключение первым блоком except, это предотвратит выполнение остальных блоков:
try:
# some code that may raise an exception
except Exception as e: # Это перехватит все ошибки
print(f'An error occurred: {e}')
except ValueError: # Это никогда не будет выполнено
print('A ValueError occurred')
except TypeError: # Это никогда не будет выполнено
print('A TypeError occurred')
В этом примере блок try может вызвать любой тип исключения. Однако первый оператор except перехватывает базовый класс Exception, поэтому он перехватит любое возникшее исключение. Будет выведено сообщение об ошибке, и остальные операторы except не будут выполнены.
Задание: Разбор файла
Вы работаете инженером-программистом в стартапе, который обрабатывает большие объемы данных. Недавно команда решила использовать файлы JSON для хранения и обработки данных. Эти данные жизненно важны для работы вашего стартапа, и ваша задача — написать программу на Python, которая читает и разбирает эти файлы JSON.
Однако из-за большого объема данных и участия многих людей часто возникают ошибки:
Иногда файл данных не существует.
Иногда файл данных пустой.
Иногда файл данных содержит данные, которые не являются корректным JSON.
Вам нужно убедиться, что ваша программа на Python может обрабатывать эти исключения без сбоев и предоставлять понятные сообщения об ошибках, чтобы команда работы с данными могла быстро выявить и исправить проблему.
Ваша программа должна принимать на вход строку, представляющую имя файла, и обрабатывать следующие случаи:
Если файл не существует, она должна вызвать FileNotFoundError и вывести соответствующее сообщение об ошибке.
Если файл пустой, она должна вызвать ValueError и вывести соответствующее сообщение об ошибке.
Если содержимое файла не является корректным JSON, она должна вызвать json.JSONDecodeError (который является подклассом ValueError) и вывести соответствующее сообщение об ошибке. При вызове этого исключения вы должны предоставить параметры doc и pos.
💡
except json.JSONDecodeError as e:
Каждое из этих исключений должно обрабатываться независимо друг от друга, и ваша программа должна предоставлять конкретное сообщение об ошибке для каждого случая.
Входные данные
Выходные данные
nonexistent_file.json
FileNotFoundError: File 'nonexistent_file.json' does not exist.
empty_file.json
ValueError: File 'empty_file.json' is empty.
invalid_json.json
JSONDecodeError: Content of file 'invalid_json.json' is not valid JSON.: line 1 column 1 (char 0)
success.json
File 'success.json' has been successfully parsed as valid JSON.