目錄
- 文件讀取操作
- 讀取文件的全部內容
- 相對路徑和絕對路徑
- 逐行訪問文件內容
- 文件寫入操作
- 寫入單行內容
- 寫入多行內容
- 結構化數據的存儲
- 異常處理機制
- 理解異常的工作原理
- ZeroDivisionError異常示例
- try-except語句塊的使用
- else語句塊的正確使用
- 靜默失敗的合理應用
本文將深入探討Python中的文件處理技術,幫助開發者構建能夠高效處理大量數據的程序。同時,我們還將重點介紹異常處理機制,確保程序在面對意外情況時能夠優雅地處理錯誤而不是崩潰。此外,還將學習如何使用json模塊持久化存儲用戶數據,防止程序結束運行后數據丟失。
文件讀取操作
在數據分析和處理應用中,文件讀取是最基礎也是最重要的操作之一。無論是分析日志文件、處理配置信息還是讀取數據集,掌握文件讀取技術都是必不可少的。
讀取文件的全部內容
Python提供了 pathlib
模塊來優雅地處理文件路徑操作。相比傳統的 os.path
方式,pathlib
提供了更加面向對象和直觀的接口。
from pathlib import Path# 創建Path對象指向目標文件
file_path = Path('data/sample.txt')# 讀取文件全部內容
try:content = file_path.read_text(encoding='utf-8')print(f"文件內容長度:{len(content)} 字符")
except FileNotFoundError:print(f"文件 {file_path} 不存在")
read_text()
方法會一次性讀取整個文件內容并返回字符串對象。建議在讀取文件時顯式指定編碼格式,避免因編碼問題導致的亂碼。
相對路徑和絕對路徑
理解路徑概念對于文件操作至關重要:
- 相對路徑: 相對于當前工作目錄的路徑,便于項目遷移和部署
- 絕對路徑: 文件在文件系統中的完整路徑,具有唯一性
from pathlib import Path# 相對路徑示例
relative_path = Path('config/settings.json')# 絕對路徑示例
absolute_path = Path('/home/user/projects/data/input.csv')# 獲取當前工作目錄
current_dir = Path.cwd()
print(f"當前工作目錄:{current_dir}")# 將相對路徑轉換為絕對路徑
abs_path = relative_path.resolve()
print(f"絕對路徑:{abs_path}")
逐行訪問文件內容
對于大型文件,逐行處理能夠有效控制內存使用:
from pathlib import Pathfile_path = Path('logs/application.log')try:content = file_path.read_text(encoding='utf-8')lines = content.splitlines()# 逐行處理for line_num, line in enumerate(lines, 1):if 'ERROR' in line:print(f"第{line_num}行發現錯誤:{line.strip()}")except FileNotFoundError:print("日志文件不存在")
文件寫入操作
文件寫入是數據持久化的重要手段,Python提供了多種寫入方式來滿足不同需求。
寫入單行內容
from pathlib import Pathoutput_path = Path('output/result.txt')# 確保目錄存在
output_path.parent.mkdir(parents=True, exist_ok=True)# 寫入單行內容
message = "數據處理完成,共處理1000條記錄"
output_path.write_text(message, encoding='utf-8')
寫入多行內容
from pathlib import Pathreport_path = Path('reports/daily_summary.txt')# 準備多行內容
lines = ["=== 每日數據處理報告 ===","處理日期:2024-01-15","總記錄數:5000","成功處理:4950","失敗記錄:50","處理耗時:120秒"
]# 寫入多行內容
content = '\n'.join(lines)
report_path.write_text(content, encoding='utf-8')
結構化數據的存儲
在實際開發中,經常需要存儲列表、字典等復雜數據結構。JSON格式因其輕量級和跨平臺特性成為首選方案:
import json
from pathlib import Path# 存儲字典數據
user_data = {"users": [{"id": 1, "name": "張三", "email": "zhangsan@example.com"},{"id": 2, "name": "李四", "email": "lisi@example.com"}],"total": 2,"last_updated": "2024-01-15T10:30:00"
}data_path = Path('data/users.json')# 使用json.dumps()序列化并寫入文件
try:with open(data_path, 'w', encoding='utf-8') as f:json.dump(user_data, f, ensure_ascii=False, indent=2)print("數據保存成功")
except IOError as e:print(f"文件寫入失敗:{e}")# 讀取JSON數據
try:with open(data_path, 'r', encoding='utf-8') as f:loaded_data = json.load(f)print(f"加載了 {loaded_data['total']} 個用戶記錄")
except (FileNotFoundError, json.JSONDecodeError) as e:print(f"數據加載失敗:{e}")
- json.dump() 函數說明:
f
:文件類對象,f 表示 fileensure_ascii=False
:不要將所有內容都轉換為ASCII字符indent=2
:默認為None
,即所有 JSON 字符會被壓縮成一行,沒有多余的空格和換行。
異常處理機制
異常處理是構建健壯應用程序的核心技術。Python通過異常對象來封裝錯誤信息,并提供了完善的異常處理機制。
理解異常的工作原理
當程序遇到錯誤時,Python解釋器會創建一個異常對象,包含錯誤類型、錯誤信息和發生位置等詳細信息。如果異常未被捕獲,程序將終止并顯示 traceback
信息。
ZeroDivisionError異常示例
def calculate_average(numbers):"""計算數字列表的平均值"""if not numbers:raise ValueError("輸入列表不能為空")try:total = sum(numbers)count = len(numbers)average = total / countreturn averageexcept ZeroDivisionError:print("錯誤:除零操作")return Noneexcept TypeError as e:print(f"錯誤:數據類型不正確 - {e}")return None# 測試用例
test_data = [10, 20, 30, 40]
result = calculate_average(test_data)
print(f"平均值:{result}")
try-except語句塊的使用
try-except
語句塊提供了結構化的異常處理方式:
from pathlib import Path
import jsondef load_config(config_path):"""加載配置文件"""try:path = Path(config_path)content = path.read_text(encoding='utf-8')config = json.loads(content)return configexcept FileNotFoundError:print(f"配置文件 {config_path} 不存在")return {}except json.JSONDecodeError as e:print(f"配置文件格式錯誤:{e}")return {}except PermissionError:print("沒有權限訪問配置文件")return {}except Exception as e:print(f"未知錯誤:{e}")return {}# 使用示例
config = load_config('config/app.json')
else語句塊的正確使用
else
語句塊只有在 try
塊成功執行且沒有異常時才會執行,適合放置依賴于 try
塊成功執行的代碼:
def process_file(file_path):"""處理文件并生成報告"""try:path = Path(file_path)content = path.read_text(encoding='utf-8')lines = content.splitlines()except FileNotFoundError:print(f"文件 {file_path} 不存在")except PermissionError:print("沒有文件訪問權限")else:# 只有文件成功讀取后才執行此部分print(f"文件讀取成功,共 {len(lines)} 行")# 生成處理報告report = {"file_path": str(file_path),"total_lines": len(lines),"non_empty_lines": len([line for line in lines if line.strip()]),"processed_at": "2024-01-15T10:30:00"}# 保存報告report_path = Path('reports/processing_report.json')with open(report_path, 'w', encoding='utf-8') as f:json.dump(report, f, ensure_ascii=False, indent=2)print("處理報告已生成")
靜默失敗的合理應用
在某些場景下,我們希望程序在遇到特定異常時繼續運行而不顯示錯誤信息。這種做法稱為"靜默失敗",但應該謹慎使用:
import json
from pathlib import Pathdef load_user_preferences(user_id):"""加載用戶偏好設置,如果失敗則返回默認設置"""pref_file = Path(f'preferences/user_{user_id}.json')try:with open(pref_file, 'r', encoding='utf-8') as f:preferences = json.load(f)except (FileNotFoundError, json.JSONDecodeError, PermissionError):# 靜默處理異常,返回默認設置preferences = {"theme": "light","language": "zh-CN","notifications": True}return preferences# 靜默失敗適用場景:
# 1. 配置文件不存在時使用默認配置
# 2. 可選功能失敗時不影響主要功能
# 3. 日志記錄失敗時不中斷業務流程# 注意:即使是靜默失敗,也應該在適當的地方記錄日志
def safe_log_action(action, user_id):"""安全記錄用戶操作,失敗時不影響主業務"""try:log_entry = {"timestamp": "2024-01-15T10:30:00","user_id": user_id,"action": action}log_path = Path('logs/user_actions.json')# 讀取現有日志if log_path.exists():with open(log_path, 'r', encoding='utf-8') as f:logs = json.load(f)else:logs = []# 添加新日志并保存logs.append(log_entry)with open(log_path, 'w', encoding='utf-8') as f:json.dump(logs, f, ensure_ascii=False, indent=2)except Exception:# 靜默失敗,但在生產環境中應該記錄到系統日志pass # 日志記錄失敗不應影響主要業務邏輯
通過掌握這些文件處理和異常處理技術,你將能夠構建更加健壯和可靠的Python應用程序。
2025.09 宣武門