Python学习第七天
什么是异常,如何捕获处理异常,比如捕获“1除以0”的异常
什么是异常?
在编程中,异常(Exception) 是指在程序执行过程中发生的、打断正常程序流程的错误或事件。当异常发生时,如果程序没有采取措施进行处理,它通常会停止运行并显示错误信息。
异常不是语法错误(Syntax Error),语法错误是在代码编译或解释阶段就发现的错误,比如你打错了关键字。异常是在程序运行时,因为某些不可预见的条件或情况(如文件不存在、网络中断、除数为零等)而导致的错误。
例如,当你尝试:
访问一个不存在的文件
网络连接突然中断
内存不足
最常见的:用一个数字除以零
这些情况下,Python 解释器会检测到一个异常,并“抛出”它。
如何捕获和处理异常?
在 Python 中,我们使用 try...except 语句来捕获(Catch) 和 处理(Handle) 异常。这样即使程序发生错误,也能优雅地继续运行,而不是直接崩溃。
try...except 语句的基本结构如下:
Python
try: # 尝试执行可能引发异常的代码块 # 如果这里的代码没有异常,except 块将被跳过 # 如果发生异常,try 块中剩余的代码将被跳过,程序流程会跳转到 except 块 except ExceptionType as e: # 当 try 块中发生 'ExceptionType' 类型的异常时,此处的代码将被执行 # 'e' 是一个可选变量,用于引用捕获到的异常对象,你可以通过它获取异常的详细信息 # 在这里处理异常,例如打印错误消息,记录日志,或者执行一些清理操作 else: # (可选) 如果 try 块中的代码没有引发任何异常,则执行此处的代码 finally: # (可选) 无论 try 块中是否发生异常,甚至在 except 或 else 块执行后, # finally 块中的代码总是会被执行 # 通常用于执行清理操作,如关闭文件或网络连接
捕获并处理“1 除以 0”的异常(ZeroDivisionError)
当你尝试用任何数字除以零时,Python 会抛出 ZeroDivisionError 异常。我们可以专门捕获这种类型的异常。
示例代码:
Python
# 示例 1: 捕获特定的 ZeroDivisionError print("--- 示例 1: 捕获 ZeroDivisionError ---") try: numerator = 10 denominator = 0 result = numerator / denominator # 这行代码会引发 ZeroDivisionError print(f"计算结果: {result}") # 这行代码将不会被执行 except ZeroDivisionError: print("错误:不能除以零!请检查你的除数。") print("程序继续执行...\n") # 即使发生异常,程序也能继续执行 # 示例 2: 捕获所有类型的异常(不推荐在生产代码中广泛使用) print("--- 示例 2: 捕获所有异常 (通用 Exception) ---") try: value = int("hello") # 这会引发 ValueError print(value) except Exception as e: # Exception 是所有内置异常的基类 print(f"发生了一个通用错误: {e}") print(f"错误类型是: {type(e)}") print("程序继续执行...\n") # 示例 3: 捕获多个特定异常 print("--- 示例 3: 捕获多个特定异常 ---") try: # test_case = 1 # 除以零 # test_case = 2 # 类型转换错误 test_case = 3 # 无错误 if test_case == 1: res = 1 / 0 elif test_case == 2: res = int("abc") else: res = "操作成功!" print(f"结果: {res}") except ZeroDivisionError: print("发生了除以零的错误!") except ValueError: print("发生了值转换错误(例如,尝试将非数字字符串转换为数字)!") except Exception as e: # 捕获其他任何未被上面捕获的异常 print(f"发生了未预期的错误: {e}") print("程序继续执行...\n") # 示例 4: try...except...else...finally 完整结构 print("--- 示例 4: 完整 try...except...else...finally 结构 ---") def divide_numbers(a, b): try: print(f"尝试计算 {a} / {b}...") result = a / b except ZeroDivisionError: print("错误:除数不能为零!") return None # 返回 None 表示失败 except TypeError: # 例如,如果 a 或 b 不是数字 print("错误:操作数类型不正确!") return None else: # 如果 try 块没有引发异常 print("计算成功完成!") return result finally: # 无论是否发生异常,都会执行 print("除法操作尝试结束。") print(f"10 / 2 = {divide_numbers(10, 2)}") print(f"10 / 0 = {divide_numbers(10, 0)}") print(f"'a' / 2 = {divide_numbers('a', 2)}") print("程序继续执行。\n")
解释:
try 块: 包含你认为可能出错的代码。Python 会尝试执行 try 块中的所有语句。
except ZeroDivisionError:: 如果在 try 块中发生了 ZeroDivisionError 类型的异常,那么 try 块的剩余部分会被跳过,并执行 except ZeroDivisionError: 下方的代码。
except Exception as e:: 这是捕获所有类型异常的通用方法。Exception 是所有内置异常的基类。使用 as e 可以让你访问异常对象本身,通常它包含错误信息。不建议仅仅使用 except Exception:,因为它会捕获所有错误,包括你可能不希望捕获的编程错误(如 NameError),这会掩盖真正的 bug。 应该尽可能地捕获特定类型的异常。
多个 except 块: 你可以为不同类型的异常定义多个 except 块。Python 会按顺序检查这些块,匹配到第一个符合的异常类型就执行相应的处理代码。
else 块(可选): 如果 try 块中的代码没有引发任何异常,else 块中的代码就会被执行。这对于那些只在没有异常时才需要执行的操作很有用。
finally 块(可选): 无论 try 块中是否发生异常,except 或 else 块是否执行,finally 块中的代码总是会被执行。它通常用于执行清理操作,例如关闭文件、释放资源、断开数据库连接等,以确保即使发生错误也能完成这些操作。
通过恰当地使用 try...except...else...finally,你的 Python 程序将更加健壮和可靠。