接下来我们将学习Python中的错误处理和异常。在编写程序时,我们经常会遇到各种错误。Python使用异常(exception)来表示在程序运行时发生的错误。了解如何处理异常对编写可靠、健壮的程序至关重要。
异常是在程序运行过程中发生的错误事件。当Python解释器遇到错误时,它会引发一个异常。例如,访问不存在的列表元素会引发IndexError
异常,而尝试除以零会引发ZeroDivisionError
异常。
以下是一个抛出异常的示例:
def divide(a, b): return a / b result = divide(4, 0) # ZeroDivisionError: division by zero
在这个例子中,我们定义了一个名为divide
的函数,用于执行除法运算。当我们尝试除以零时,Python会抛出ZeroDivisionError
异常。
为了处理异常,我们可以使用try
和except
语句。try
语句用于包裹可能引发异常的代码块,而except
语句用于捕获特定类型的异常并执行相应的代码块。
以下是一个处理异常的示例:
def safe_divide(a, b): try: return a / b except ZeroDivisionError: print("Cannot divide by zero!") return None result = safe_divide(4, 0) # Cannot divide by zero! print(result) # None
在这个例子中,我们定义了一个名为safe_divide
的函数,用于执行除法运算。我们使用try
语句包裹可能引发异常的代码,并使用except
语句捕获ZeroDivisionError
异常。当异常发生时,我们打印一条错误消息并返回None
。
except
语句我们可以使用多个except
语句来处理不同类型的异常。例如:
def safe_divide(a, b): try: return a / b except ZeroDivisionError: print("Cannot divide by zero!") return None except TypeError: print("Invalid input!") return None result = safe_divide(4, "two") # Invalid input! print(result) # None
在这个例子中,我们增加了一个except
语句来捕获TypeError
异常。当我们尝试使用一个非数值类型作为除数时,Python会抛出TypeError
异常。
finally
语句finally
语句用于指定无论异常是否发生,都需要执行的代码块。例如:
def safe_divide(a, b): try: return a / b except ZeroDivisionError: print("Cannot divide by zero!") return None except TypeError: print("Invalid input!") return None finally: print("Finished dividing.") result = safe_divide(4, 2) # Finished dividing. print(result) # 2.0 result = safe_divide(4, 0) # Cannot divide by zero! # Finished dividing. print(result) # None
在这个例子中,我们使用finally
语句指定了一个无论异常是否发生,都需要执行的代码块。在这种情况下,我们在每次调用safe_divide
函数时都会打印"Finished dividing."。
我们可以通过继承BaseException
类或其子类来定义自定义异常。例如:
class InvalidInputError(Exception): pass def safe_divide(a, b): if not isinstance(a, (int, float)) or not isinstance(b, (int, float)): raise InvalidInputError("Both a and b must be numbers.") if b == 0: raise ZeroDivisionError("Cannot divide by zero.") return a / b try: result = safe_divide(4, "two") except InvalidInputError as e: print(e) # Both a and b must be numbers. 在这个例子中,我们定义了一个名为`InvalidInputError`的自定义异常类,用于表示无效的输入。我们修改了`safe_divide`函数,使其在遇到无效输入时抛出`InvalidInputError`异常。然后我们使用`try`和`except`语句捕获并处理这个异常。 ### 6. 异常链 有时,我们可能需要在处理异常时引发新的异常。为了保留原始异常的上下文信息,我们可以使用`raise ... from ...`语句来创建异常链。例如: ```python class ParsingError(Exception): pass def parse_number(number_string): try: return int(number_string) except ValueError as e: raise ParsingError("Invalid number format.") from e try: result = parse_number("12a") except ParsingError as e: print(f"{e} - Original exception: {e.__cause__}")
在这个例子中,我们定义了一个名为ParsingError
的自定义异常类,用于表示解析错误。我们创建了一个名为parse_number
的函数,该函数尝试将字符串转换为整数。当转换失败时,我们使用raise ... from ...
语句引发一个新的ParsingError
异常,并保留原始ValueError
异常作为上下文信息。
断言(assertion)是一种用于检查程序中的条件是否满足预期的调试工具。当断言条件为False
时,Python会抛出一个AssertionError
异常。我们可以使用assert
语句来编写断言。例如:
def calculate_area(width, height): assert width > 0, "Width must be positive." assert height > 0, "Height must be positive." return width * height try: area = calculate_area(-1, 5) except AssertionError as e: print(e) # Width must be positive.
在这个例子中,我们创建了一个名为calculate_area
的函数,用于计算矩形的面积。我们使用assert
语句来检查输入的宽度和高度是否为正数。当输入不满足条件时,会抛出一个AssertionError
异常。
请注意,断言应仅用于调试程序和捕获非预期的错误。在生产环境中,您应该使用异常处理来处理可能的错误情况。
这就是Python中错误处理与异常的基本概念。希望这些示例能帮助你更好地理解如何在Python中处理异常。如果你有任何问题,请随时提问。