python中用于异常处理的关键字详解

内容分享22小时前发布
1 0 0

我们来详细讲解 Python 中用于异常处理的关键字。

异常处理是编程中超级重大的概念,它允许程序在遇到错误时优雅地处理问题,而不是直接崩溃。Python 提供了一套完整的关键字来处理异常

一、异常处理核心关键字

1.try- 尝试执行

  • 功能:用于包裹可能会抛出异常的代码块。
  • 位置:必须是异常处理块的开始。
  • 规则:try 块必须至少有一个 except 或 finally 块配合使用。

2.except- 捕获异常

  • 功能:用于捕获和处理在 try 块中发生的特定异常。
  • 变体
    • except ExceptionType: 捕获特定类型的异常
    • except ExceptionType as e: 捕获异常并获取异常对象
    • except: 捕获所有类型的异常(不推荐常规使用)
    • 多个 except 块:处理不同类型的异常

3.else- 无异常时执行

  • 功能:当 try 块中的代码没有抛出任何异常时执行。
  • 位置:必须在所有 except 块之后,finally 块之前。

4.finally- 最终执行

  • 功能无论是否发生异常都会执行的代码块。
  • 用途:一般用于清理资源,如关闭文件、数据库连接等。

二、主动引发异常关键字

5.raise- 抛出异常

  • 功能主动抛出一个异常。
  • 用途:在检测到错误条件时主动引发异常,或者在处理异常后重新抛出。

6.assert- 断言

  • 功能:用于调试,检查条件是否为真。如果条件为假,则抛出 AssertionError 异常。
  • 特点:可以用 -O(优化)参数运行 Python 来禁用所有断言。

三、完整语法结构

try:
    # 可能会抛出异常的代码
    ...
except ExceptionType1 as e:
    # 处理 ExceptionType1 类型的异常
    ...
except ExceptionType2:
    # 处理 ExceptionType2 类型的异常
    ...
except:
    # 处理所有其他异常(谨慎使用)
    ...
else:
    # 如果没有异常发生,执行这里的代码
    ...
finally:
    # 无论是否发生异常,都会执行的代码
    ...

四、详细示例

示例 1:基本的异常处理

try:
    num = int(input("请输入一个数字: "))
    result = 10 / num
    print(f"结果是: {result}")
except ValueError:
    print("错误:请输入有效的数字!")
except ZeroDivisionError:
    print("错误:不能除以零!")
except Exception as e:
    print(f"发生了未知错误: {e}")
else:
    print("计算成功完成!")
finally:
    print("程序执行结束。")

# 可能的输出:
# 请输入一个数字: abc
# 错误:请输入有效的数字!
# 程序执行结束。

示例 2:使用 else 和 finally

def read_file(filename):
    try:
        file = open(filename, 'r')
        content = file.read()
    except FileNotFoundError:
        print(f"文件 {filename} 不存在")
        return None
    except PermissionError:
        print("没有读取文件的权限")
        return None
    else:
        print("文件读取成功")
        return content
    finally:
        # 确保文件总是被关闭
        if 'file' in locals() and not file.closed:
            file.close()
            print("文件已关闭")

content = read_file("example.txt")

示例 3:主动抛出异常 (raise)

def calculate_age(birth_year):
    if birth_year < 1900 or birth_year > 2023:
        raise ValueError("出生年份必须在1900-2023之间")
    return 2023 - birth_year

try:
    age = calculate_age(1800)
    print(f"年龄: {age}")
except ValueError as e:
    print(f"输入错误: {e}")

# 重新抛出异常
try:
    risky_operation()
except Exception as e:
    print(f"记录错误: {e}")
    raise  # 重新抛出一样的异常

示例 4:自定义异常

class InsufficientFundsError(Exception):
    """自定义异常:余额不足"""
    def __init__(self, balance, amount):
        self.balance = balance
        self.amount = amount
        super().__init__(f"余额不足!当前余额: {balance}, 需要: {amount}")

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(balance, amount)
    return balance - amount

try:
    new_balance = withdraw(100, 150)
except InsufficientFundsError as e:
    print(e)  # 输出: 余额不足!当前余额: 100, 需要: 150

示例 5:断言 (assert)

def calculate_average(numbers):
    """计算数字列表的平均值"""
    assert len(numbers) > 0, "列表不能为空"
    assert all(isinstance(num, (int, float)) for num in numbers), "所有元素必须是数字"
    
    return sum(numbers) / len(numbers)

# 正常情况
print(calculate_average([1, 2, 3, 4, 5]))  # 输出: 3.0

# 会触发断言错误
try:
    calculate_average([])
except AssertionError as e:
    print(f"断言错误: {e}")  # 输出: 断言错误: 列表不能为空

示例 6:多个异常处理

def process_data(data):
    try:
        # 尝试多种可能失败的操作
        value = data['key']  # 可能KeyError
        number = int(value)  # 可能ValueError
        result = 100 / number  # 可能ZeroDivisionError
        
    except KeyError:
        print("错误:字典中不存在该键")
    except ValueError:
        print("错误:无法转换为数字")
    except ZeroDivisionError:
        print("错误:不能除以零")
    else:
        print(f"处理结果: {result}")
        return result
    finally:
        print("数据处理流程结束")

# 测试不同的错误情况
process_data({'key': '10'})    # 正常
process_data({'wrong': '10'})  # KeyError
process_data({'key': 'abc'})   # ValueError
process_data({'key': '0'})     # ZeroDivisionError

五、常见的异常类型

异常类型

描述

Exception

所有内置异常的基类

ValueError

值错误,如 int('abc')

TypeError

类型错误,如 'a' + 1

IndexError

索引错误,如 list[10](列表只有3个元素)

KeyError

键错误,如 dict['nonexistent']

FileNotFoundError

文件未找到错误

ZeroDivisionError

除以零错误

AttributeError

属性错误,如 None.some_method()


总结表

关键字

功能描述

示例

try

尝试执行可能出错的代码

try:

except

捕获和处理异常

except ValueError:

else

无异常时执行的代码

else:

finally

无论是否异常都执行的代码

finally:

raise

主动抛出异常

raise ValueError(“错误”)

assert

断言检查,用于调试

assert x > 0, “x必须大于0”

最佳实践提议

  1. 具体异常:尽量捕获具体的异常类型,而不是使用空的 except:。
  2. 资源清理:使用 finally 或上下文管理器(with 语句)来确保资源被正确释放。
  3. 异常信息:在抛出异常时提供有意义的错误信息。
  4. 不要过度使用:异常处理应该用于真正的异常情况,而不是普通的控制流。

掌握这些异常处理关键字可以让你的程序更加健壮和可靠。

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...