Собственный класс исключений не проходит неизвестные тесты
Мне для выполнения задания нужно написать программу со следующими условиями:
- Собственный класс исключений
Напишите класс исключения
ParseError
, который будет являться наследником классаException
.
Снабдите созданный класс документ-строкой: """ Error while parsing file """.
Конструктор класса
ParseError
должен принимать необязательные именованные аргументыline_no
(номер строки) иtext
(текст, который вызвал ошибку).Опишите метод
__str__
, создающий сообщение об ошибке по следующей логике:
если не переданы ни номер строки, ни текст, вызывается стандартный метод
Exception
;если передан только номер строки, метод выдает "cannot parse text on line ...";
если передан только текст, метод выдает "cannot parse text: '...'" (текст должен выглядеть так, как его выдает функция
repr
);если переданы и номер строки, и текст, метод выдает: "cannot parse text on line ...: '...'".
Пример работы программы:
>>> raise ParseError('some standard message') Traceback (most recent call last): ... __main__.ParseError: some standard message >>> raise ParseError(line_no=10) Traceback (most recent call last): ... __main__.ParseError: cannot parse text on line 10 >>> raise ParseError(text='abc') Traceback (most recent call last): __main__.ParseError: cannot parse text: 'abc' >>> raise ParseError(line_no=10, text='...') Traceback (most recent call last): ... __main__.ParseError: cannot parse text on line 10: '...'
Пояснение: любой класс исключения принимает произвольное число аргументов (в сигнатуре функции это выглядит как
*args
). Класс-наследник должен поддерживать весь интерфейс родителя, поэтому в вашем классе также должны быть*args
, которые нужно передать выше по иерархии наследования с помощью функцииsuper
.Любые аргументы, указанные после аргумента со «звездочкой», можно передать только по имени, поэтому они называются именованными. Чтобы сделать их необязательными, нужно дать им значение по умолчанию.
Я написал следующую программу, но она не проходит тесты, которые неизвестны:
class ParseError(Exception):
""" Error while parsing file """
def __init__(self, line_no=None, text=None):
self.line_no = line_no
self.text = text
def __str__(self):
if self.line_no == None and self.text == None:
return f"some standard message"
elif self.text == None:
return f"cannot parse text on line {self.line_no}"
elif self.line_no == None:
return "cannot parse text: " + repr(self.text)
else:
return f"cannot parse text on line {self.line_no}: " + repr(self.text)
Подскажите, что я делаю неправильно?
Ответы (2 шт):
Мне кажется метод __str__
не нужно переопределять. Пусть срабатывает стандартный из Exception. Достаточно на основании двух именованных параметров задавать текст, который должен вывести Exception. Для этого в наследнике в методе __init__
смотрим на два этих параметра и формируем нужное сообщение об ошибке, либо ничего не делаем и инициализируем Exception со стандартным *args. Т.к. по условию задания не требуется дальнейшая обработка именованных параметров, то и хранить их в атрибутах экземпляра не нужно. Т.к. args - это кортеж, то для унификации сгенерированное сообщение об ошибке оборачиваем в кортеж.
class ParseError(Exception):
""" Error while parsing file """
def __init__(self, *args, line_no=None, text=None):
match (line_no is None, text is None):
case (False, True):
args = (f"cannot parse text on line {line_no}",)
case (True, False):
args = (f"cannot parse text on line {text!r}",)
case (False, False):
args = (f"cannot parse text on line {line_no}: {text!r}",)
super().__init__(*args)
Вот такой код благополучно проходит проверки:
class ParseError(Exception):
""" Error while parsing file """
def __init__(self, *args, line_no=None, text=None):
super().__init__(*args)
match (line_no is None, text is None):
case (True, True):
self.text = super().__str__()
case (True, False):
self.text = f'cannot parse text: \'{text}\''
case (False, True):
self.text = f'cannot parse text on line {line_no}'
case (False, False):
self.text = f'cannot parse text on line {line_no}: \'{text}\''
def __str__(self):
return self.text