在Python中,try-except 块用于捕获和处理异常。当 try 块中的代码发生错误时,程序会跳转到对应的 except 块执行。
基本语法结构
try:
# 可能引发异常的代码
risky_operation()
except ExceptionType as e:
# 处理特定类型的异常
print(f"发生错误: {e}")
except AnotherExceptionType as e:
# 处理另一种类型的异常
print(f"另一种错误: {e}")
else:
# 如果没有发生异常,执行这里的代码
print("操作成功完成")
finally:
# 无论是否发生异常,都会执行这里的代码
print("清理操作")常见的文件操作异常类型
1. FileNotFoundError
try:
with open('不存在的文件.txt', 'r', encoding='utf-8') as file:
content = file.read()
except FileNotFoundError as e:
print(f"文件不存在错误: {e}")
print(f"错误文件名: {e.filename}")
print(f"错误编号: {e.errno}")2. PermissionError
try:
with open('/root/受保护的文件.txt', 'w', encoding='utf-8') as file:
file.write('test')
except PermissionError as e:
print(f"权限错误: {e}")
print(f"操作: {e.args[0]}")3. UnicodeDecodeError
try:
with open('二进制文件.jpg', 'r', encoding='utf-8') as file:
content = file.read()
except UnicodeDecodeError as e:
print(f"编码错误: {e}")
print(f"错误位置: {e.start}-{e.end}")
print(f"原因: 尝试用文本模式读取二进制文件")4. IsADirectoryError
try:
with open('/某个目录/', 'r', encoding='utf-8') as file:
content = file.read()
except IsADirectoryError as e:
print(f"尝试打开目录而不是文件: {e}")5. IOError (Python 3.3+ 中是 OSError 的别名)
try:
with open('file.txt', 'r', encoding='utf-8') as file:
content = file.read()
except IOError as e:
print(f"输入输出错误: {e}")错误信息解析方法
获取详细的错误信息
try:
with open('nonexistent.txt', 'r') as file:
content = file.read()
except Exception as e:
print(f"异常类型: {type(e).__name__}")
print(f"错误信息: {e}")
print(f"错误参数: {e.args}")
print(f"完整追溯: {e.__traceback__}")使用 traceback 模块获取完整堆栈信息
import traceback
try:
with open('problematic.txt', 'r', encoding='utf-8') as file:
content = file.read()
except Exception as e:
print("发生异常:")
traceback.print_exc() # 打印完整的堆栈跟踪
# 或者获取堆栈信息字符串
error_traceback = traceback.format_exc()
print("完整的错误信息:")
print(error_traceback)实际应用示例
示例1:安全的文件读取函数
def safe_read_file(filename):
"""
安全读取文件,返回文件内容或错误信息
"""
try:
with open(filename, 'r', encoding='utf-8') as file:
return file.read(), None # 返回内容和None(表示无错误)
except FileNotFoundError as e:
return None, f"错误:文件 '{filename}' 不存在"
except PermissionError as e:
return None, f"错误:没有权限读取文件 '{filename}'"
except UnicodeDecodeError as e:
return None, f"错误:文件编码问题,请检查文件格式"
except Exception as e:
return None, f"未知错误:{e}"
# 使用示例
content, error = safe_read_file('example.txt')
if error:
print(error)
else:
print("文件内容:", content)示例2:带重试机制的文件操作
import time
def read_file_with_retry(filename, max_retries=3, delay=1):
"""
带重试机制的文件读取
"""
for attempt in range(max_retries):
try:
with open(filename, 'r', encoding='utf-8') as file:
return file.read()
except FileNotFoundError as e:
if attempt == max_retries - 1: # 最后一次尝试
raise e
print(f"文件不存在,{delay}秒后重试... ({attempt + 1}/{max_retries})")
time.sleep(delay)
except Exception as e:
print(f"尝试 {attempt + 1} 失败: {e}")
if attempt == max_retries - 1:
raise e
time.sleep(delay)示例3:详细的错误日志记录
import logging
import datetime
# 配置日志
logging.basicConfig(
filename='file_errors.log',
level=logging.ERROR,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def log_file_operation(operation_func, *args, **kwargs):
"""
包装文件操作,记录详细的错误日志
"""
try:
return operation_func(*args, **kwargs)
except Exception as e:
error_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
error_info = {
'time': error_time,
'operation': operation_func.__name__,
'args': args,
'kwargs': kwargs,
'error_type': type(e).__name__,
'error_message': str(e)
}
logging.error(f"文件操作错误: {error_info}")
print(f"操作失败,详情已记录到日志。错误: {e}")
return None
# 使用示例
def read_my_file(filename):
with open(filename, 'r', encoding='utf-8') as file:
return file.read()
result = log_file_operation(read_my_file, 'example.txt')示例4:多异常类型处理
def handle_file_errors(filename, mode='r'):
try:
with open(filename, mode, encoding='utf-8') as file:
if mode == 'r':
return file.read()
else:
return True # 写入成功
except FileNotFoundError as e:
print(f"❌ 文件未找到: {filename}")
print(f" 请检查文件路径是否正确")
return False
except PermissionError as e:
print(f"❌ 权限不足: {filename}")
print(f" 请检查文件权限或是否被其他程序占用")
return False
except UnicodeDecodeError as e:
print(f"❌ 编码错误: {filename}")
print(f" 请尝试使用不同的编码或检查文件格式")
return False
except IsADirectoryError as e:
print(f"❌ 尝试打开目录: {filename}")
print(f" 请提供文件路径而不是目录路径")
return False
except Exception as e:
print(f"❌ 未知错误: {type(e).__name__} - {e}")
return False最佳实践
- 具体异常优先: 先捕获具体的异常类型,最后捕获通用的 Exception
- 提供有意义的错误信息: 告诉用户发生了什么以及如何解决
- 记录错误日志: 对于生产环境,记录详细的错误信息
- 适当的错误恢复: 根据错误类型决定是重试、跳过还是终止
- 资源清理: 使用
finally块或with语句确保资源释放
通过这样的错误处理机制,你可以创建更加健壮和用户友好的文件操作程序。
















