Python 异常处理

Python 的异常处理机制允许程序在发生错误时采取适当的应对措施,而不会立即终止运行。通过异常处理,你可以捕获并处理运行时的错误,从而使程序更加健壮和稳定。

异常处理的基本结构

Python 使用 try-except 结构来处理异常。基本语法如下:

try:
    # 尝试执行的代码
except ExceptionType:
    # 如果发生指定类型的异常,执行这段代码

1. 基本的 try-except 结构

try:
    x = 10 / 0  # 可能会引发异常的代码
except ZeroDivisionError:
    print("除数不能为零")

在这个例子中,当程序尝试执行 10 / 0 时,会抛出 ZeroDivisionErrorexcept 块捕获到这个异常,并输出相应的信息,而不是让程序崩溃。

2. 捕获多个异常

你可以通过多个 except 块捕获不同类型的异常:

try:
    x = int(input("请输入一个数字: "))
    result = 10 / x
except ValueError:
    print("输入的不是一个有效的数字")
except ZeroDivisionError:
    print("不能除以零")

在这个例子中,可能发生两种异常:用户输入的不是一个有效的数字(ValueError),或者用户输入了零(ZeroDivisionError)。不同的异常会触发不同的 except 块。

如果想要对多种异常执行相同的处理操作:

try:
    x = int(input("请输入一个数字: "))
    result = 10 / x
except (ValueError, ZeroDivisionError):
    print('输入的数字有误,请检查输入。')

3. 捕获所有异常

如果你不确定会发生什么异常,可以使用 Exception 类捕获所有异常:

try:
    x = int(input("请输入一个数字: "))
    result = 10 / x
except Exception as e:
    print(f"发生了异常: {e}")

这种方式会捕获所有的异常,并将异常信息存储在变量 e 中,可以在 except 块中使用。

4. else

else 块在 try 块中代码没有引发异常时执行:

try:
    x = int(input("请输入一个数字: "))
    result = 10 / x
except ZeroDivisionError:
    print("不能除以零")
except ValueError:
    print("输入的不是一个有效的数字")
else:
    print(f"结果是: {result}")

在这个例子中,如果没有发生异常,程序会执行 else 块中的代码,并输出计算结果。

5. finally

finally 块无论是否发生异常,都会执行,常用于释放资源或进行清理操作:

try:
    file = open("example.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("文件未找到")
finally:
    file.close()
    print("文件已关闭")

在这个例子中,无论是否发生 FileNotFoundErrorfinally 块都会确保文件被关闭。

注意:即使在函数中有return 返回 finally中的类容也会被执行。

def test():
    try:
        x = int(input("输入数字:"))
        result = 10 / x
        print(f"结果为{result}。")
        return
    except (ZeroDivisionError, ValueError):
        print("发现错误。")
        return
    finally:
        print("最后执行finally。")


test()

# 输入数字:1
# 结果为10.0
# 最后执行finally。

# 输入数字:0
# 发现错误。
# 最后执行finally。

6. 自定义异常

你可以通过继承 Exception 类来自定义异常:

class CustomError(Exception):
    def __init__(self, message):
        self.message = message

try:
    raise CustomError("这是一个自定义异常")
except CustomError as e:
    print(f"捕获到自定义异常: {e.message}")

在这个例子中,CustomError 是一个自定义异常,可以通过 raise 关键字手动抛出并捕获。

7. raise 关键字

raise 关键字用于手动引发异常:

def check_age(age):
    if age < 18:
        raise ValueError("年龄必须大于或等于 18")
    return True

try:
    check_age(16)
except ValueError as e:
    print(e)

在这个例子中,check_age() 函数如果接收到小于 18 的年龄,会抛出 ValueError 异常。

8. 断言(assert

assert 语句用于测试表达式的正确性,如果表达式为 False,则会引发 AssertionError 异常:

def divide(a, b):
    assert b != 0, "除数不能为零"
    return a / b

print(divide(10, 2))  # 正常执行
print(divide(10, 0))  # 引发 AssertionError: 除数不能为零

9.异常类型

1. BaseException 类
  • 所有异常的基类。
2. 常见异常类型
系统退出和中断
  • SystemExit: 解释器请求退出。
  • KeyboardInterrupt: 用户中断执行,通常是按 Ctrl+C
  • GeneratorExit: 生成器(generator)退出时抛出的异常。
标准异常
  • Exception: 常规异常的基类。
  • StopIteration: 迭代器没有更多项时抛出。
  • StopAsyncIteration: 异步迭代器没有更多项时抛出。
逻辑错误
  • ArithmeticError: 所有数值计算错误的基类。

    • FloatingPointError: 浮点运算错误。
    • OverflowError: 数值运算导致结果超出范围。
    • ZeroDivisionError: 除数为零。
  • AssertionError: 断言语句失败时抛出(assert)。

  • AttributeError: 尝试访问不存在的对象属性。

  • BufferError: 与缓冲区相关的操作引发的问题。

  • EOFError: 遇到文件结束符(EOF),而没有读取到足够数据时抛出。

  • ImportError: 模块导入失败时抛出。

    • ModuleNotFoundError: 找不到模块时引发的异常(ImportError 的子类)。
  • LookupError: 无效查找操作的基类。

    • IndexError: 序列索引超出范围。
    • KeyError: 字典中找不到指定的键。
  • MemoryError: 内存不足时抛出。

  • NameError: 访问未定义的变量。

    • UnboundLocalError: 访问局部变量前未绑定值(NameError 的子类)。
  • OSError: 操作系统错误的基类。

    • BlockingIOError: 操作会阻塞(例如非阻塞操作不能立即完成)。

    • ChildProcessError: 子进程相关的错误。

    • ConnectionError: 与连接相关的错误。

      • BrokenPipeError: 管道破裂错误。
      • ConnectionAbortedError: 连接中止错误。
      • ConnectionRefusedError: 连接被拒绝错误。
      • ConnectionResetError: 连接被重置错误。
    • FileExistsError: 尝试创建文件或目录时,文件或目录已存在。

    • FileNotFoundError: 尝试访问不存在的文件或目录。

    • InterruptedError: 系统调用被中断。

    • IsADirectoryError: 文件操作目标是一个目录,但要求的是文件。

    • NotADirectoryError: 文件操作目标不是目录,但要求的是目录。

    • PermissionError: 没有执行操作的权限。

    • ProcessLookupError: 无法找到指定的进程。

    • TimeoutError: 操作超时。

I/O错误
  • IOError: 输入/输出操作失败的基类(在 Python 3 中是 OSError 的别名)。
运行时错误
  • RuntimeError: 一般的运行时错误。
    • NotImplementedError: 未实现的方法。
    • RecursionError: 递归层次过深。
类型错误
  • TypeError: 操作或函数应用于不适当的类型。

  • ValueError: 函数接收到具有正确类型但不适合的值。

    • UnicodeError: Unicode 相关的错误(ValueError 的子类)。
      • UnicodeDecodeError: 解码过程中发生错误。
      • UnicodeEncodeError: 编码过程中发生错误。
      • UnicodeTranslateError: 转换过程中发生错误。
编码错误
  • EncodingError: 字符串编码/解码的错误。
系统相关错误
  • SystemError: 解释器内部发生错误,但不严重。
  • ReferenceError: 弱引用(weakref)尝试访问已垃圾回收的对象。
  • OverflowError: 算术操作导致数值超出表示范围。
  • MemoryError: 内存不足时引发的异常。
警告类异常
  • Warning: 警告的基类。
    • UserWarning: 用户代码生成的警告。
    • DeprecationWarning: 与已弃用功能相关的警告。
    • SyntaxWarning: 与语法相关的警告。
    • RuntimeWarning: 与运行时情况相关的警告。
    • FutureWarning: 关于未来语义更改的警告。
语法错误
  • SyntaxError: Python 语法错误。
    • IndentationError: 缩进错误。
      • TabError: 不一致的制表符和空格缩进。

总结

Python 的异常处理机制通过 try-except-else-finally 结构,使得程序可以优雅地处理各种可能的错误情况。通过捕获特定异常、捕获所有异常、自定义异常和使用 raise 关键字,你可以让你的程序在错误情况下依然保持稳定,并输出有用的错误信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值