MST
星途 面试题库

面试题:Python自定义异常与异常链的应用

设计一个Python模块,该模块实现了一个简单的数学表达式解析器。解析器需要处理各种语法错误,例如操作符错误、括号不匹配等。请定义自定义异常类来表示这些错误,并在捕获异常时,将异常信息以异常链的形式传递,使得调用者能够清晰地追踪异常发生的完整路径以及原始的错误原因。请给出完整的代码实现,并解释异常链在这个场景中的作用。
49.9万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
class ParserError(Exception):
    pass

class OperatorError(ParserError):
    pass

class ParenthesesError(ParserError):
    pass

def parse_math_expression(expression):
    try:
        # 简单示例,这里可以使用更完善的语法解析逻辑
        parts = expression.split()
        if len(parts) != 3:
            raise OperatorError("操作符错误,表达式格式应为:数字 操作符 数字")
        num1, operator, num2 = parts
        num1 = float(num1)
        num2 = float(num2)
        if operator not in ['+', '-', '*', '/']:
            raise OperatorError("不支持的操作符")
        if operator == '/' and num2 == 0:
            raise ZeroDivisionError("除数不能为零")
        if expression.count('(') != expression.count(')'):
            raise ParenthesesError("括号不匹配")
        if operator == '+':
            return num1 + num2
        elif operator == '-':
            return num1 - num2
        elif operator == '*':
            return num1 * num2
        elif operator == '/':
            return num1 / num2
    except (OperatorError, ParenthesesError) as e:
        raise ParserError("解析错误") from e
    except ZeroDivisionError as e:
        raise ParserError("解析错误,出现除零错误") from e
    except ValueError as e:
        raise ParserError("解析错误,无法将部分转换为数字") from e


异常链在这个场景中的作用:

  1. 清晰的错误追踪:当parse_math_expression函数抛出异常时,异常链可以让调用者看到异常最初发生的原因。例如,如果在处理表达式时,由于输入的操作符不支持导致OperatorError异常,而这个异常又被ParserError捕获并以异常链的形式重新抛出。调用者捕获到ParserError时,可以通过__cause__属性追溯到最初的OperatorError,清楚地知道是操作符的问题导致了最终的解析错误。

  2. 分层错误处理:通过自定义不同类型的异常,如OperatorErrorParenthesesError,可以在模块内部进行精细的错误分类处理。而外层的调用者可以通过捕获更通用的ParserError,同时又能从异常链中获取具体的错误细节,实现了分层的错误处理机制,提高了代码的可读性和维护性。