在 Python 中,错误和异常是程序运行时可能遇到的问题。正确处理它们可以使程序更加健壮。
目录
1. 错误类型
Python中的错误主要分为两类:
-
语法错误(SyntaxError):代码不符合Python语法规则
-
异常(Exception):运行时检测到的错误
-
语法错误(SyntaxError):代码不符合 Python 语法规则
print("Hello world' # 错误:缺少闭合引号
-
名称错误(NameError):使用未定义的变量
print(undefined_variable)
-
类型错误(TypeError):对不兼容类型进行操作
"2" + 2
-
索引错误(IndexError):访问不存在的索引
lst = [1, 2, 3] print(lst[3])
-
键错误(KeyError):访问字典中不存在的键
d = {'a': 1} print(d['b'])
-
属性错误(AttributeError):访问不存在的属性
s = "hello" s.append('!')
-
值错误(ValueError):传入无效参数
int("abc")
2. 异常处理
异常捕捉可以使用 try/except 语句
else 子句将在 try 子句没有发生任何异常的时候执行
try-finally 语句无论是否发生异常都将执行最后的代码。
基本异常处理结构:
try:
# 可能引发异常的代码
result = 10 / int(input("输入除数: "))
except ValueError:
print("请输入数字!")
except ZeroDivisionError:
print("除数不能为零!")
except Exception as e: # 捕获所有其他异常
print(f"发生未知错误: {e}")
else:
print(f"结果为: {result}") # 无异常时执行
finally:
print("执行结束") # 无论是否异常都会执行
3. 抛出异常
使用raise
主动抛出异常
def login(username, password):
if not username or not password:
raise ValueError("用户名和密码不能为空")
if len(password) < 6:
raise ValueError("密码长度不能少于6位")
# 验证逻辑...
try:
login("", "123")
except ValueError as e:
print(f"登录失败: {e}")
4. 自定义异常
可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。
创建自定义异常类:
class InsufficientFundsError(Exception):
"""账户余额不足异常"""
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(f"余额不足! 当前余额:{balance}, 需要:{amount}")
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
return self.balance
try:
account = BankAccount(100)
account.withdraw(150)
except InsufficientFundsError as e:
print(e) # 输出: 余额不足! 当前余额:100, 需要:150
5. 定义清理行为
使用finally
确保资源释放
file = None
try:
file = open("data.txt", "r")
data = file.read()
print(data)
except FileNotFoundError:
print("文件不存在")
finally:
if file: # 确保文件对象被关闭
file.close()
print("资源清理完成")
更简洁的方式是使用with
语句:
try:
with open("data.txt", "r") as file:
data = file.read()
print(data)
except FileNotFoundError:
print("文件不存在")
6. 断言
使用assert
进行调试检查
def calculate_average(numbers):
assert len(numbers) > 0, "数字列表不能为空"
return sum(numbers) / len(numbers)
try:
print(calculate_average([])) # 触发AssertionError
except AssertionError as e:
print(f"断言错误: {e}")
7. 应用实例
实例1:用户输入验证
def get_positive_number():
while True:
try:
num = float(input("请输入正数: "))
if num <= 0:
raise ValueError("必须输入正数")
return num
except ValueError as e:
print(f"无效输入: {e}")
number = get_positive_number()
print(f"您输入的正数是: {number}")
实例2:文件处理
def process_file(filename):
try:
with open(filename, 'r') as file:
lines = file.readlines()
print(f"文件内容({len(lines)}行):")
for i, line in enumerate(lines, 1):
print(f"{i}: {line.strip()}")
except FileNotFoundError:
print(f"错误: 文件 '{filename}' 不存在")
except PermissionError:
print(f"错误: 没有权限读取文件 '{filename}'")
except Exception as e:
print(f"处理文件时发生未知错误: {e}")
process_file("example.txt")
实例3:API请求处理
import requests
def fetch_data(url):
try:
response = requests.get(url, timeout=5)
response.raise_for_status() # 如果请求失败会抛出HTTPError
return response.json()
except requests.exceptions.Timeout:
print("请求超时")
except requests.exceptions.HTTPError as err:
print(f"HTTP错误: {err}")
except requests.exceptions.RequestException as err:
print(f"请求错误: {err}")
except ValueError as err:
print(f"JSON解析错误: {err}")
return None
data = fetch_data("https://api.example.com/data")
if data:
print("获取数据成功:", data)
通过合理使用异常处理机制,可以编写出更加健壮、可维护的Python代码。