更新时间2026-05-21 | 阅读时长15分钟 技术栈Python / 文件操作 / 异常处理 / pathlibPython文件与异常处理代码健壮性的两大基石2026最新教程在实际项目中我们经常遇到这样的问题文件不存在、读取权限不够、网络中断、JSON格式错误……这些问题如果不处理程序直接崩溃用户体验极差。本文系统讲解Python文件操作与异常处理让你的代码从一碰就碎变成刀枪不入。一、文件操作基础1.1 文件读写三部曲python复制# 第一步打开文件 f open(data.txt, r, encodingutf-8) # 第二步读写操作 content f.read() # 第三步关闭文件 f.close()但更推荐使用with语句自动管理文件关闭python复制# 读取文件 with open(data.txt, r, encodingutf-8) as f: content f.read() print(content) # 写入文件 with open(output.txt, w, encodingutf-8) as f: f.write(Hello, Python!\n) f.write(文件操作其实很简单。) # 追加内容 with open(output.txt, a, encodingutf-8) as f: f.write(\n追加一行新内容。)1.2 常见读取方式python复制# 一次性读取全部 with open(data.txt, r, encodingutf-8) as f: content f.read() print(content) # 按行读取 with open(data.txt, r, encodingutf-8) as f: for line in f: print(line.strip()) # 读取所有行到列表 with open(data.txt, r, encodingutf-8) as f: lines f.readlines() for i, line in enumerate(lines): print(f{i1}: {line.strip()}) # 按字符数读取适合大文件 with open(big_data.txt, r, encodingutf-8) as f: while True: chunk f.read(1024) # 每次读1KB if not chunk: break print(chunk)二、文件操作高级技巧2.1 文件路径处理pathlibpython复制from pathlib import Path # 获取项目根目录 project_root Path(__file__).parent # 构建路径跨平台兼容 data_file project_root / data / users.csv config_file project_root / config / settings.json # 判断路径是否存在 print(data_file.exists()) # True/False # 创建目录 output_dir project_root / output / 2026 output_dir.mkdir(parentsTrue, exist_okTrue) # 文件重命名 old_file project_root / old_name.txt new_file project_root / new_name.txt old_file.rename(new_file) # 复制文件 import shutil shutil.copy(source.txt, destination.txt) # 删除文件 new_file.unlink() # 删除单个文件 # shutil.rmtree(folder) # 删除整个文件夹2.2 CSV文件操作python复制import csv # 写入CSV with open(users.csv, w, encodingutf-8, newline) as f: writer csv.writer(f) writer.writerow([姓名, 年龄, 城市]) writer.writerow([张三, 25, 北京]) writer.writerow([李四, 30, 上海]) writer.writerow([王五, 28, 广州]) # 读取CSV with open(users.csv, r, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: print(f{row[姓名]} - {row[年龄]}岁 - 住在{row[城市]}) # 使用pandas读写CSV更强大 import pandas as pd df pd.read_csv(users.csv) print(df) df.to_csv(new_users.csv, indexFalse, encodingutf-8)2.3 JSON文件操作python复制import json # 写入JSON data { name: AI实验室2026, topics: [Python, 机器学习, 数据分析], stats: {followers: 10000, articles: 9} } with open(blog.json, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2) # 读取JSON with open(blog.json, r, encodingutf-8) as f: loaded_data json.load(f) print(loaded_data[name]) print(loaded_data[topics]) # 字符串与JSON互转 json_str json.dumps(data, ensure_asciiFalse) parsed json.loads(json_str)2.4 批量文件操作python复制from pathlib import Path import shutil # 列出目录下所有文件 current_dir Path(.) for file in current_dir.iterdir(): if file.is_file(): print(f文件: {file.name}) # 按扩展名筛选 py_files list(Path(.).glob(*.py)) print(f共找到 {len(py_files)} 个Python文件) # 批量重命名 photos_dir Path(photos) for i, photo in enumerate(photos_dir.glob(*.jpg), 1): new_name fphoto_{i:03d}.jpg photo.rename(photos_dir / new_name) print(f{photo.name} - {new_name}) # 批量复制文件 src_dir Path(source) dst_dir Path(backup) dst_dir.mkdir(exist_okTrue) for file in src_dir.glob(*.txt): shutil.copy(file, dst_dir / file.name)三、异常处理让程序不崩溃3.1 为什么要处理异常python复制# 没有异常处理 - 程序直接崩溃 def read_config(filename): f open(filename, r) # 文件不存在直接报错退出 content f.read() f.close() return content # 有异常处理 - 程序优雅应对 def read_config_safe(filename): try: with open(filename, r, encodingutf-8) as f: return f.read() except FileNotFoundError: print(f错误配置文件 {filename} 不存在) return None except PermissionError: print(f错误没有读取 {filename} 的权限) return None3.2 完整的异常处理结构python复制try: # 可能出错的代码 result 10 / 0 data json.loads(invalid_json_string) except ZeroDivisionError: # 处理特定异常 print(除数不能为零) except json.JSONDecodeError as e: # 捕获异常对象获取详细信息 print(fJSON解析错误: {e.msg}) print(f错误位置: 行{e.lineno}, 列{e.colno}) except (FileNotFoundError, PermissionError) as e: # 同时处理多种异常 print(f文件操作错误: {e}) except Exception as e: # 兜底处理所有未预料的异常 print(f未知错误: {type(e).__name__}: {e}) else: # try块没抛异常时执行 print(一切正常执行完毕) finally: # 不管有没有异常都执行常用于清理工作 print(无论成功还是失败这里都会执行。)3.3 主动抛出异常python复制def validate_age(age): if not isinstance(age, int): raise TypeError(年龄必须是整数) if age 0 or age 150: raise ValueError(f年龄 {age} 不合理) return True # 使用函数 try: validate_age(-5) except ValueError as e: print(f验证失败: {e}) # 验证失败: 年龄 -5 不合理 try: validate_age(二十五) except TypeError as e: print(f验证失败: {e}) # 验证失败: 年龄必须是整数3.4 自定义异常类python复制class ValidationError(Exception): 数据验证错误 def __init__(self, field, message): self.field field self.message message super().__init__(f{field}: {message}) class DataProcessor: def process(self, data): if not data: raise ValidationError(data, 数据不能为空) if not isinstance(data, dict): raise ValidationError(data, 数据必须是字典类型) if name not in data: raise ValidationError(name, 缺少必需字段 name) print(f处理数据: {data}) return True processor DataProcessor() try: processor.process({name: 测试}) except ValidationError as e: print(f验证错误: {e.field} - {e.message})四、实战案例文件处理与异常结合4.1 配置文件读取器python复制import json from pathlib import Path class ConfigManager: def __init__(self, config_fileconfig.json): self.config_file Path(config_file) self.config {} def load(self): 加载配置文件 try: with open(self.config_file, r, encodingutf-8) as f: self.config json.load(f) print(f配置加载成功: {self.config_file}) return self.config except FileNotFoundError: print(f配置文件不存在创建默认配置: {self.config_file}) self.config self._get_default_config() self.save() # 创建默认配置文件 return self.config except json.JSONDecodeError as e: print(f配置文件格式错误: {e}) print(使用默认配置。) self.config self._get_default_config() return self.config def _get_default_config(self): 默认配置 return { theme: light, language: zh-CN, max_results: 100, debug: False } def save(self): 保存配置 try: with open(self.config_file, w, encodingutf-8) as f: json.dump(self.config, f, ensure_asciiFalse, indent2) print(f配置已保存: {self.config_file}) except Exception as e: print(f保存配置失败: {e}) # 使用配置管理器 config ConfigManager(settings.json) settings config.load() print(settings)4.2 批量文件处理器带异常处理python复制from pathlib import Path import json class BatchFileProcessor: def __init__(self, source_dir, target_dir): self.source Path(source_dir) self.target Path(target_dir) self.results {success: [], failed: []} def process_all(self): 处理目录下所有JSON文件 if not self.source.exists(): print(f源目录不存在: {self.source}) return self.results self.target.mkdir(parentsTrue, exist_okTrue) for json_file in self.source.glob(*.json): self._process_file(json_file) self._print_summary() return self.results def _process_file(self, file_path): 处理单个JSON文件 try: with open(file_path, r, encodingutf-8) as f: data json.load(f) # 简单处理添加元数据 processed { original_file: file_path.name, data: data, processed: True } # 保存到目标目录 output_file self.target / fprocessed_{file_path.name} with open(output_file, w, encodingutf-8) as f: json.dump(processed, f, ensure_asciiFalse, indent2) self.results[success].append(file_path.name) print(f✓ 处理成功: {file_path.name}) except json.JSONDecodeError as e: self.results[failed].append({ file: file_path.name, error: fJSON格式错误: {e} }) print(f✗ JSON错误: {file_path.name} - {e}) except PermissionError: self.results[failed].append({ file: file_path.name, error: 没有读取权限 }) print(f✗ 权限错误: {file_path.name}) except Exception as e: self.results[failed].append({ file: file_path.name, error: str(e) }) print(f✗ 处理失败: {file_path.name} - {e}) def _print_summary(self): 打印处理摘要 total len(self.results[success]) len(self.results[failed]) print(f\n处理完成: 共{total}个文件) print(f成功: {len(self.results[success])}个) print(f失败: {len(self.results[failed])}个) if self.results[failed]: print(\n失败详情:) for item in self.results[failed]: print(f - {item[file]}: {item[error]}) # 使用批量处理器 processor BatchFileProcessor(json_files, output) results processor.process_all()五、最佳实践5.1 异常处理原则❌ 不要捕获所有异常然后什么都不做 try: risky_operation() except: pass ✓ 应该捕获具体异常并处理 try: risky_operation() except SpecificError as e: handle_error(e) raise # 必要时重新抛出5.2 使用日志记录错误python复制import logging # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(app.log, encodingutf-8), logging.StreamHandler() ] ) logger logging.getLogger(__name__) def process_data(filename): try: with open(filename, r) as f: return f.read() except FileNotFoundError: logger.error(f文件不存在: {filename}) raise except PermissionError: logger.error(f没有权限: {filename}) raise5.3 异常处理与文件操作的黄金法则python复制# ✗ 错误示范 file open(data.txt) try: # 操作 finally: file.close() # 如果open失败这里也会报错 # ✓ 正确做法 try: with open(data.txt, r) as f: # 操作 # with自动关闭文件 except FileNotFoundError: # 处理错误六、总结本文介绍了Python文件操作与异常处理的核心技能技能关键点文件读写使用with语句自动管理资源路径处理pathlib跨平台兼容CSV/JSONpandas json库批量操作glob模式匹配异常处理try-except-finally结构自定义异常面向业务的错误类型日志记录logging模块记录错误健壮的代码不是一蹴而就的学会处理异常是成为成熟开发者的必经之路。
AI实验室2026_第9篇_Python文件与异常处理教程
更新时间2026-05-21 | 阅读时长15分钟 技术栈Python / 文件操作 / 异常处理 / pathlibPython文件与异常处理代码健壮性的两大基石2026最新教程在实际项目中我们经常遇到这样的问题文件不存在、读取权限不够、网络中断、JSON格式错误……这些问题如果不处理程序直接崩溃用户体验极差。本文系统讲解Python文件操作与异常处理让你的代码从一碰就碎变成刀枪不入。一、文件操作基础1.1 文件读写三部曲python复制# 第一步打开文件 f open(data.txt, r, encodingutf-8) # 第二步读写操作 content f.read() # 第三步关闭文件 f.close()但更推荐使用with语句自动管理文件关闭python复制# 读取文件 with open(data.txt, r, encodingutf-8) as f: content f.read() print(content) # 写入文件 with open(output.txt, w, encodingutf-8) as f: f.write(Hello, Python!\n) f.write(文件操作其实很简单。) # 追加内容 with open(output.txt, a, encodingutf-8) as f: f.write(\n追加一行新内容。)1.2 常见读取方式python复制# 一次性读取全部 with open(data.txt, r, encodingutf-8) as f: content f.read() print(content) # 按行读取 with open(data.txt, r, encodingutf-8) as f: for line in f: print(line.strip()) # 读取所有行到列表 with open(data.txt, r, encodingutf-8) as f: lines f.readlines() for i, line in enumerate(lines): print(f{i1}: {line.strip()}) # 按字符数读取适合大文件 with open(big_data.txt, r, encodingutf-8) as f: while True: chunk f.read(1024) # 每次读1KB if not chunk: break print(chunk)二、文件操作高级技巧2.1 文件路径处理pathlibpython复制from pathlib import Path # 获取项目根目录 project_root Path(__file__).parent # 构建路径跨平台兼容 data_file project_root / data / users.csv config_file project_root / config / settings.json # 判断路径是否存在 print(data_file.exists()) # True/False # 创建目录 output_dir project_root / output / 2026 output_dir.mkdir(parentsTrue, exist_okTrue) # 文件重命名 old_file project_root / old_name.txt new_file project_root / new_name.txt old_file.rename(new_file) # 复制文件 import shutil shutil.copy(source.txt, destination.txt) # 删除文件 new_file.unlink() # 删除单个文件 # shutil.rmtree(folder) # 删除整个文件夹2.2 CSV文件操作python复制import csv # 写入CSV with open(users.csv, w, encodingutf-8, newline) as f: writer csv.writer(f) writer.writerow([姓名, 年龄, 城市]) writer.writerow([张三, 25, 北京]) writer.writerow([李四, 30, 上海]) writer.writerow([王五, 28, 广州]) # 读取CSV with open(users.csv, r, encodingutf-8) as f: reader csv.DictReader(f) for row in reader: print(f{row[姓名]} - {row[年龄]}岁 - 住在{row[城市]}) # 使用pandas读写CSV更强大 import pandas as pd df pd.read_csv(users.csv) print(df) df.to_csv(new_users.csv, indexFalse, encodingutf-8)2.3 JSON文件操作python复制import json # 写入JSON data { name: AI实验室2026, topics: [Python, 机器学习, 数据分析], stats: {followers: 10000, articles: 9} } with open(blog.json, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2) # 读取JSON with open(blog.json, r, encodingutf-8) as f: loaded_data json.load(f) print(loaded_data[name]) print(loaded_data[topics]) # 字符串与JSON互转 json_str json.dumps(data, ensure_asciiFalse) parsed json.loads(json_str)2.4 批量文件操作python复制from pathlib import Path import shutil # 列出目录下所有文件 current_dir Path(.) for file in current_dir.iterdir(): if file.is_file(): print(f文件: {file.name}) # 按扩展名筛选 py_files list(Path(.).glob(*.py)) print(f共找到 {len(py_files)} 个Python文件) # 批量重命名 photos_dir Path(photos) for i, photo in enumerate(photos_dir.glob(*.jpg), 1): new_name fphoto_{i:03d}.jpg photo.rename(photos_dir / new_name) print(f{photo.name} - {new_name}) # 批量复制文件 src_dir Path(source) dst_dir Path(backup) dst_dir.mkdir(exist_okTrue) for file in src_dir.glob(*.txt): shutil.copy(file, dst_dir / file.name)三、异常处理让程序不崩溃3.1 为什么要处理异常python复制# 没有异常处理 - 程序直接崩溃 def read_config(filename): f open(filename, r) # 文件不存在直接报错退出 content f.read() f.close() return content # 有异常处理 - 程序优雅应对 def read_config_safe(filename): try: with open(filename, r, encodingutf-8) as f: return f.read() except FileNotFoundError: print(f错误配置文件 {filename} 不存在) return None except PermissionError: print(f错误没有读取 {filename} 的权限) return None3.2 完整的异常处理结构python复制try: # 可能出错的代码 result 10 / 0 data json.loads(invalid_json_string) except ZeroDivisionError: # 处理特定异常 print(除数不能为零) except json.JSONDecodeError as e: # 捕获异常对象获取详细信息 print(fJSON解析错误: {e.msg}) print(f错误位置: 行{e.lineno}, 列{e.colno}) except (FileNotFoundError, PermissionError) as e: # 同时处理多种异常 print(f文件操作错误: {e}) except Exception as e: # 兜底处理所有未预料的异常 print(f未知错误: {type(e).__name__}: {e}) else: # try块没抛异常时执行 print(一切正常执行完毕) finally: # 不管有没有异常都执行常用于清理工作 print(无论成功还是失败这里都会执行。)3.3 主动抛出异常python复制def validate_age(age): if not isinstance(age, int): raise TypeError(年龄必须是整数) if age 0 or age 150: raise ValueError(f年龄 {age} 不合理) return True # 使用函数 try: validate_age(-5) except ValueError as e: print(f验证失败: {e}) # 验证失败: 年龄 -5 不合理 try: validate_age(二十五) except TypeError as e: print(f验证失败: {e}) # 验证失败: 年龄必须是整数3.4 自定义异常类python复制class ValidationError(Exception): 数据验证错误 def __init__(self, field, message): self.field field self.message message super().__init__(f{field}: {message}) class DataProcessor: def process(self, data): if not data: raise ValidationError(data, 数据不能为空) if not isinstance(data, dict): raise ValidationError(data, 数据必须是字典类型) if name not in data: raise ValidationError(name, 缺少必需字段 name) print(f处理数据: {data}) return True processor DataProcessor() try: processor.process({name: 测试}) except ValidationError as e: print(f验证错误: {e.field} - {e.message})四、实战案例文件处理与异常结合4.1 配置文件读取器python复制import json from pathlib import Path class ConfigManager: def __init__(self, config_fileconfig.json): self.config_file Path(config_file) self.config {} def load(self): 加载配置文件 try: with open(self.config_file, r, encodingutf-8) as f: self.config json.load(f) print(f配置加载成功: {self.config_file}) return self.config except FileNotFoundError: print(f配置文件不存在创建默认配置: {self.config_file}) self.config self._get_default_config() self.save() # 创建默认配置文件 return self.config except json.JSONDecodeError as e: print(f配置文件格式错误: {e}) print(使用默认配置。) self.config self._get_default_config() return self.config def _get_default_config(self): 默认配置 return { theme: light, language: zh-CN, max_results: 100, debug: False } def save(self): 保存配置 try: with open(self.config_file, w, encodingutf-8) as f: json.dump(self.config, f, ensure_asciiFalse, indent2) print(f配置已保存: {self.config_file}) except Exception as e: print(f保存配置失败: {e}) # 使用配置管理器 config ConfigManager(settings.json) settings config.load() print(settings)4.2 批量文件处理器带异常处理python复制from pathlib import Path import json class BatchFileProcessor: def __init__(self, source_dir, target_dir): self.source Path(source_dir) self.target Path(target_dir) self.results {success: [], failed: []} def process_all(self): 处理目录下所有JSON文件 if not self.source.exists(): print(f源目录不存在: {self.source}) return self.results self.target.mkdir(parentsTrue, exist_okTrue) for json_file in self.source.glob(*.json): self._process_file(json_file) self._print_summary() return self.results def _process_file(self, file_path): 处理单个JSON文件 try: with open(file_path, r, encodingutf-8) as f: data json.load(f) # 简单处理添加元数据 processed { original_file: file_path.name, data: data, processed: True } # 保存到目标目录 output_file self.target / fprocessed_{file_path.name} with open(output_file, w, encodingutf-8) as f: json.dump(processed, f, ensure_asciiFalse, indent2) self.results[success].append(file_path.name) print(f✓ 处理成功: {file_path.name}) except json.JSONDecodeError as e: self.results[failed].append({ file: file_path.name, error: fJSON格式错误: {e} }) print(f✗ JSON错误: {file_path.name} - {e}) except PermissionError: self.results[failed].append({ file: file_path.name, error: 没有读取权限 }) print(f✗ 权限错误: {file_path.name}) except Exception as e: self.results[failed].append({ file: file_path.name, error: str(e) }) print(f✗ 处理失败: {file_path.name} - {e}) def _print_summary(self): 打印处理摘要 total len(self.results[success]) len(self.results[failed]) print(f\n处理完成: 共{total}个文件) print(f成功: {len(self.results[success])}个) print(f失败: {len(self.results[failed])}个) if self.results[failed]: print(\n失败详情:) for item in self.results[failed]: print(f - {item[file]}: {item[error]}) # 使用批量处理器 processor BatchFileProcessor(json_files, output) results processor.process_all()五、最佳实践5.1 异常处理原则❌ 不要捕获所有异常然后什么都不做 try: risky_operation() except: pass ✓ 应该捕获具体异常并处理 try: risky_operation() except SpecificError as e: handle_error(e) raise # 必要时重新抛出5.2 使用日志记录错误python复制import logging # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(app.log, encodingutf-8), logging.StreamHandler() ] ) logger logging.getLogger(__name__) def process_data(filename): try: with open(filename, r) as f: return f.read() except FileNotFoundError: logger.error(f文件不存在: {filename}) raise except PermissionError: logger.error(f没有权限: {filename}) raise5.3 异常处理与文件操作的黄金法则python复制# ✗ 错误示范 file open(data.txt) try: # 操作 finally: file.close() # 如果open失败这里也会报错 # ✓ 正确做法 try: with open(data.txt, r) as f: # 操作 # with自动关闭文件 except FileNotFoundError: # 处理错误六、总结本文介绍了Python文件操作与异常处理的核心技能技能关键点文件读写使用with语句自动管理资源路径处理pathlib跨平台兼容CSV/JSONpandas json库批量操作glob模式匹配异常处理try-except-finally结构自定义异常面向业务的错误类型日志记录logging模块记录错误健壮的代码不是一蹴而就的学会处理异常是成为成熟开发者的必经之路。