Python常见异常类型及处理方法

Python 拥有丰富的内置异常,它们都继承自一个共同的基类 BaseException。最常见的异常则继承自 Exception 类。

了解这些异常对于调试和编写健壮的代码至关重要。下面我将它们分为几类进行介绍。


一、最常见的异常(几乎每个程序员都会遇到)

这些是学习 Python 初期就会频繁碰到的异常。

  1. SyntaxError (语法错误)

    • 原因:代码不符合 Python 的语法规则,无法被解析。
    • 示例
      if True
          print("Hello")  # 缺少冒号 `:`
      # 或
      print("Hello"  # 括号不匹配
      
  2. IndentationError (缩进错误)

    • 原因:缩进不正确。这是 SyntaxError 的一个子类,但因为非常重要且常见,所以单独列出。
    • 示例
      if True:
      print("Hello")  # 这一行缩进量不对
      # 或混用空格和制表符
      
  3. NameError (名称错误)

    • 原因:尝试访问一个未定义的变量或函数名。
    • 示例
      print(undefined_variable)  # 这个变量从未被赋值
      
  4. TypeError (类型错误)

    • 原因:操作或函数应用于不适当类型的对象。
    • 常见场景
      • 对非可迭代对象进行迭代:for i in 123:
      • 执行不兼容类型的操作:‘a’ + 1
      • 函数调用时参数数量正确但类型错误:len(100)
      • 调用对象不是函数:a = 1; a()
  5. ValueError (值错误)

    • 原因:操作或函数接收到的参数类型正确,但值不合法。
    • 示例
      int("abc")   # 字符串"abc"无法转换成整数
      x = [1, 2, 3]
      x.index(4)   # 4 不在列表里,无法找到其索引
      
  6. IndexError (索引错误)

    • 原因:序列(如列表、元组、字符串)的索引超出范围。
    • 示例
      my_list = [1, 2, 3]
      print(my_list[5])  # 列表只有3个元素,索引5不存在
      
  7. KeyError (键错误)

    • 原因:尝试访问字典中不存在的键。
    • 示例
      my_dict = {'a': 1}
      print(my_dict['b'])  # 键 'b' 不存在
      
  8. AttributeError (属性错误)

    • 原因:尝试访问对象没有的属性或方法。
    • 示例
      x = 10
      x.append(1)  # 整数没有 append 方法
      
  9. ModuleNotFoundError (模块未找到错误)

    • 原因import 语句无法找到指定的模块。
    • 示例
      import non_existent_module
      
  10. ZeroDivisionError (零除错误)

    • 原因:试图用 0 作为除数。
    • 示例
      result = 10 / 0
      

二、与IO操作相关的异常

在处理文件或输入输出时常见。

  1. FileNotFoundError (文件未找到错误)

    • 原因:尝试打开一个不存在的文件。
    • 示例
      with open('non_existent_file.txt', 'r') as f:
          content = f.read()
      
  2. PermissionError (权限错误)

    • 原因:没有足够的权限来执行文件操作(如读取、写入、执行)。
    • 示例:尝试向一个只读文件写入内容。
  3. IsADirectoryError / NotADirectoryError

    • 原因:试图将一个目录当作文件操作,或反之。
    • 示例open('/tmp', 'r')/tmp 是一个目录)

三、与迭代和生成器相关的异常

  1. StopIteration (迭代停止)

    • 原因:由迭代器的 __next__() 方法引发,表示迭代器中已经没有更多元素了。通常你不需要手动捕获它,因为 for 循环会自动处理。
  2. GeneratorExit (生成器退出)

    • 原因:当一个生成器被关闭时(例如调用 .close() 方法),生成器内部会收到这个异常,以便进行清理工作。

四、其他重要异常

  1. ImportError (导入错误)

    • 原因import 语句找到了模块,但无法从中加载某个特定的名称(如函数、类、子模块)。ModuleNotFoundError 是它的子类。
    • 示例
      from math import non_existent_function
      
  2. RuntimeError (运行时错误)

    • 原因:一个不归属于任何其他类别的通用错误。它通常表示一个意想不到的问题。
  3. KeyboardInterrupt (键盘中断)

    • 原因:用户按下了中断键(通常是 Ctrl+C)。它继承自 BaseException 而不是 Exception,所以在某些捕获所有 Exception 的代码中可能不会被捕获。
  4. AssertionError (断言错误)

    • 原因assert 语句后的条件求值为 False
    • 示例
      assert 1 == 2, “One does not equal two!”
      
  5. UnicodeError 及其子类(如 UnicodeDecodeError, UnicodeEncodeError)

    • 原因:在编码或解码 Unicode 字符串时发生错误。

如何处理异常:try...except

为了编写健壮的程序,你需要捕获并处理这些异常。

try:
    # 可能会出错的代码
    num = int(input("请输入一个数字: "))
    result = 10 / num
    print(f"结果是:{result}")

except ValueError:
    # 处理值错误(例如输入了字母)
    print("错误:请输入一个有效的数字!")

except ZeroDivisionError:
    # 处理零除错误
    print("错误:不能除以零!")

except Exception as e:
    # 一个宽泛的异常捕获,处理其他所有未预料到的错误
    print(f"发生了一个未知错误:{e}")

else:
    # 如果没有发生异常,则执行 else 块
    print("计算成功!")

finally:
    # 无论是否发生异常,finally 块中的代码都会执行
    # 常用于清理资源(如关闭文件)
    print("程序执行完毕。")

最佳实践

  • 尽量捕获具体的异常,而不是一个宽泛的 except:except Exception:
  • 使用 as 关键字来获取异常对象的详细信息。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值