Python的异常处理机制是一种强大的错误处理方式,使用try、except、finally和else关键字来捕获和处理程序运行过程中的错误。本文将详细介绍Python异常处理的各种用法。
一、基本语法
1. try-except结构
1 2 3 4 5 6
| try: result = 10 / 0 except ZeroDivisionError: print("不能除以零")
|
2. 捕获异常信息
1 2 3 4 5
| try: result = 10 / 0 except ZeroDivisionError as e: print(f"错误类型: {type(e).__name__}") print(f"错误信息: {e}")
|
3. 多个except子句
1 2 3 4 5 6 7
| try: value = int("abc") result = 10 / 0 except ValueError: print("值错误:无法转换为整数") except ZeroDivisionError: print("除零错误")
|
4. 捕获所有异常
1 2 3 4 5 6
| try: result = 10 / 0 except Exception as e: print(f"发生错误: {e}") except: print("发生未知错误")
|
二、else子句
1. 基本用法
else子句在没有异常发生时执行:
1 2 3 4 5 6
| try: result = 10 / 2 except ZeroDivisionError: print("除零错误") else: print(f"计算结果: {result}")
|
2. 与if-else的区别
1 2 3 4 5 6 7 8
| try: num = int(input("输入一个数字: ")) except ValueError: print("无效输入") else: print(f"你输入的是: {num}")
|
三、finally子句
1. 基本用法
finally子句无论是否有异常都会执行:
1 2 3 4 5 6 7 8
| try: file = open("test.txt", "r") content = file.read() except FileNotFoundError: print("文件不存在") finally: print("清理工作")
|
2. 典型应用场景
1 2 3 4 5 6 7 8 9
| try: file = open("test.txt", "r") content = file.read() print(content) except Exception as e: print(f"错误: {e}") finally: file.close()
|
四、Python与C++异常处理的对比
1. 语法对比
C++:
1 2 3 4 5 6 7 8 9
| try { throw std::runtime_error("Error message"); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; } catch (...) { }
|
Python:
1 2 3 4 5 6 7 8 9
| try: raise ValueError("错误信息") except ValueError as e: print(e) except Exception: pass
|
2. 异常类型
C++:使用标准异常类或自定义异常类
Python:内置多种异常类型,如ZeroDivisionError、ValueError、TypeError等
五、常见异常类型
1. 内置异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| try: result = 10 / 0 except ZeroDivisionError: print("除零错误")
try: num = int("abc") except ValueError: print("值错误")
try: result = "hello" + 123 except TypeError: print("类型错误")
try: lst = [1, 2, 3] print(lst[10]) except IndexError: print("索引错误")
try: d = {"a": 1} print(d["b"]) except KeyError: print("键错误")
|
2. 自定义异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class ValidationError(Exception): def __init__(self, message): self.message = message super().__init__(self.message)
def validate_age(age): if age < 0: raise ValidationError("年龄不能为负数") if age > 150: raise ValidationError("年龄超出合理范围")
try: validate_age(-5) except ValidationError as e: print(f"验证错误: {e.message}")
|
六、综合示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
""" 异常处理综合示例 """
class BankAccount: def __init__(self, balance=0): if balance < 0: raise ValueError("初始余额不能为负数") self._balance = balance
def deposit(self, amount): try: if amount <= 0: raise ValueError("存款金额必须为正数") self._balance += amount return self._balance except ValueError as e: print(f"存款失败: {e}") return None
def withdraw(self, amount): try: if amount <= 0: raise ValueError("取款金额必须为正数") if amount > self._balance: raise ValueError("余额不足") self._balance -= amount return self._balance except ValueError as e: print(f"取款失败: {e}") return None
@property def balance(self): return self._balance
def safe_divide(a, b): """安全除法""" try: result = a / b except ZeroDivisionError: print("错误: 除数不能为零") return None else: print(f"计算成功: {a} / {b} = {result}") return result finally: print("除法运算结束")
def read_config(filename): """读取配置文件""" config = {} try: with open(filename, 'r') as f: for line in f: line = line.strip() if line and not line.startswith('#'): key, value = line.split('=') config[key.strip()] = value.strip() except FileNotFoundError: print(f"配置文件 {filename} 不存在") except ValueError: print(f"配置文件格式错误") else: print("配置文件读取成功") finally: return config
def demo(): """演示""" print("=== 安全除法 ===") safe_divide(10, 2) safe_divide(10, 0)
print("\n=== 银行账户 ===") account = BankAccount(100) print(f"初始余额: {account.balance}") account.deposit(50) print(f"存款后余额: {account.balance}") account.withdraw(30) print(f"取款后余额: {account.balance}") account.withdraw(200)
print("\n=== 读取配置 ===") config = read_config("config.txt")
if __name__ == "__main__": demo()
|
七、注意事项
1. 不要过度使用异常处理
1 2 3 4 5 6 7 8 9 10 11
| try: result = my_list.pop() except IndexError: result = None
if my_list: result = my_list.pop() else: result = None
|
2. 异常捕获的顺序
1 2 3 4 5 6 7
| try: result = 10 / 0 except Exception: print("Exception") except ZeroDivisionError: print("ZeroDivisionError")
|
3. 使用finally进行清理
1 2 3 4 5 6 7 8 9 10
| conn = None try: conn = create_connection() result = conn.query("SELECT * FROM table") except Exception as e: print(f"查询失败: {e}") finally: if conn: conn.close()
|