Python學(xué)習(xí)教程之文件操作詳解
前言
最近在學(xué)習(xí)Python,將所學(xué)內(nèi)容整理成文章,以便以后翻閱和復(fù)習(xí),同時分享給大家。有問題歡迎隨時指正。
一、文件操作基礎(chǔ)
1、打開文件
open(file_path, mode, encoding)
file_path
:文件路徑,可以是相對路徑或絕對路徑。mode
:打開模式,常用模式包括:
模式 | 描述 |
---|---|
r | 只讀(默認(rèn)) |
w | 寫入(覆蓋原文件) |
a | 追加寫入 |
x | 創(chuàng)建新文件并寫入 |
b | 二進(jìn)制模式(如 rb , wb ) |
+ | 讀寫模式(如 r+ , w+ ) |
# 示例:打開文件(推薦使用 with 自動管理資源) with open('example.txt', 'r', encoding='utf-8') as f: content = f.read()
2、關(guān)閉文件
close()
# 手動打開并關(guān)閉文件(不推薦,容易忘記關(guān)閉) f = open('demo.txt', 'w', encoding='utf-8') f.write('Hello World') f.close() # 必須顯式關(guān)閉
對比with
語句(推薦方式)
# 使用 with 自動關(guān)閉(最佳實(shí)踐) with open('demo.txt', 'w') as f: f.write('Auto-closed file') # 等效于: f = open('demo.txt', 'w') try: f.write('Auto-closed file') finally: f.close()
實(shí)際場景中的關(guān)閉必要性
# 案例:文件未關(guān)閉導(dǎo)致寫入失敗 def write_data(): f = open('data.txt', 'w') f.write('Important data') # 忘記 f.close() → 數(shù)據(jù)可能仍在緩沖區(qū)未寫入磁盤 # 正確寫法: def safe_write(): with open('data.txt', 'w') as f: f.write('Saved data') # with 塊結(jié)束自動關(guān)閉并寫入磁盤 # 立即讀取剛寫入的內(nèi)容 with open('data.txt', 'w') as f: f.write('Test') with open('data.txt', 'r') as f: # 必須重新打開才能讀取新內(nèi)容 print(f.read()) # 輸出 Test
二、讀取文件
1、讀取全部內(nèi)容
read()
with open('example.txt', 'r') as f: data = f.read() # 返回整個文件內(nèi)容的字符串
2、逐行讀取
readline()
with open('example.txt', 'r') as f: line = f.readline() # 讀取一行 while line: print(line.strip()) # 去除末尾換行符 line = f.readline()
3、讀取所有行到列表
with open('example.txt', 'r') as f: lines = f.readlines() # 返回包含所有行的列表 for line in lines: print(line.strip())
三、寫入文件
1、寫入字符串
write(text)
with open('output.txt', 'w') as f: f.write('Hello, World!\n') # 寫入內(nèi)容(覆蓋模式)
2、寫入多行
writelines(lines)
lines = ['Line 1\n', 'Line 2\n'] with open('output.txt', 'w') as f: f.writelines(lines) # 寫入列表中的每行內(nèi)容
2.1、常見使用場景
場景1:從其他數(shù)據(jù)源生成行
# 將數(shù)值列表轉(zhuǎn)為文本行 numbers = [1, 2, 3, 4, 5] lines = [f"數(shù)值: {n}\n" for n in numbers] with open('data.log', 'w') as f: f.writelines(lines) # 輸出: # 數(shù)值: 1 # 數(shù)值: 2 # 數(shù)值: 3 # 數(shù)值: 4 # 數(shù)值: 5
場景2:追加模式寫入
# 在已有文件后追加新行 new_lines = ["追加行1\n", "追加行2\n"] with open('existing_file.txt', 'a', encoding='utf-8') as f: f.writelines(new_lines)
場景3:動態(tài)生成內(nèi)容
import datetime # 生成帶時間戳的日志行 timestamps = [ f"[{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 事件 {i}\n" for i in range(3) ] with open('events.log', 'w') as f: f.writelines(timestamps) # 輸出示例: # [2023-08-20 09:15:23] 事件 0 # [2023-08-20 09:15:23] 事件 1 # [2023-08-20 09:15:23] 事件 2
2.2、注意事項(xiàng)與常見錯誤
錯誤1:忘記換行符
# 錯誤寫法:所有內(nèi)容擠在一行 lines = ["內(nèi)容A", "內(nèi)容B", "內(nèi)容C"] with open('wrong.txt', 'w') as f: f.writelines(lines) # 輸出:內(nèi)容A內(nèi)容B內(nèi)容C # 正確寫法: lines = ["內(nèi)容A\n", "內(nèi)容B\n", "內(nèi)容C\n"]
錯誤2:非字符串類型
# 錯誤案例:包含非字符串元素 mixed_data = ["文本\n", 123, True] with open('error.txt', 'w') as f: # f.writelines(mixed_data) # 將拋出 TypeError # 解決方案:轉(zhuǎn)換為字符串 f.writelines([str(item)+'\n' for item in mixed_data])
2.3、高級用法
方法1:配合生成器處理大文件
def generate_large_data(num_lines): """生成大文件數(shù)據(jù)""" for i in range(num_lines): yield f"這是第 {i+1} 行數(shù)據(jù)\n" # 使用生成器避免內(nèi)存爆炸 # 寫入100萬行(內(nèi)存友好) with open('bigfile.txt', 'w') as f: f.writelines(generate_large_data(1_000_000))
方法2:二進(jìn)制模式寫入
# 寫入二進(jìn)制換行符(Windows換行符為\r\n) lines = [ b"Binary line 1\r\n", b"Binary line 2\r\n" ] with open('binary_file.bin', 'wb') as f: f.writelines(lines)
2.4、性能對比
方法 | 10萬行耗時 | 內(nèi)存占用 | 適用場景 |
---|---|---|---|
write() 循環(huán) | 0.45s | 高 | 需要逐行處理 |
writelines() | 0.12s | 低 | 批量寫入 |
生成器 + writelines() | 0.15s | 極低 | 超大文件 |
2.5、最佳實(shí)踐總結(jié)
始終添加換行符:
writelines
不會自動添加換行類型統(tǒng)一:確保列表元素都是字符串類型
大文件優(yōu)化:使用生成器替代列表存儲所有行
模式選擇:
'w'
:覆蓋寫入'a'
:追加寫入
搭配使用:常與列表推導(dǎo)式結(jié)合快速生成內(nèi)容
# 典型安全寫法示例 data = [f"處理結(jié)果: {x}\n" for x in some_dataset] with open('result.txt', 'w') as f: f.writelines(data)
3、追加寫入
使用模式 a
with open('output.txt', 'a') as f: f.write('Appended line.\n')
四、文件指針操作
獲取當(dāng)前位置:
tell()
移動指針:
seek(offset, whence)
whence
:0(文件開頭),1(當(dāng)前位置),2(文件末尾)
with open('example.txt', 'r') as f: f.seek(5) # 移動指針到第5字節(jié) print(f.read(3)) # 讀取接下來3個字符 print(f.tell()) # 輸出當(dāng)前指針位置
五、二進(jìn)制文件操作
使用 b
模式處理非文本文件(如圖片、視頻):
# 復(fù)制圖片 with open('input.jpg', 'rb') as src, open('copy.jpg', 'wb') as dst: data = src.read() dst.write(data)
六、實(shí)際工作場景中的常見代碼示例
1、日志文件處理(按條件過濾)
import re from pathlib import Path def filter_logs(input_file, output_file, keyword, start_time=None): """ 從日志文件中提取包含關(guān)鍵字的行,并可選時間范圍 :param input_file: 輸入日志文件路徑 :param output_file: 輸出結(jié)果文件路徑 :param keyword: 需要過濾的關(guān)鍵字 :param start_time: 起始時間(格式:2023-08-01 10:00:00) """ input_path = Path(input_file) if not input_path.exists(): raise FileNotFoundError(f"日志文件 {input_file} 不存在") pattern = re.compile(r'\[(.*?)\]') # 假設(shè)日志時間格式為 [2023-08-01 10:00:00] with open(input_file, 'r', encoding='utf-8') as f_in, \ open(output_file, 'w', encoding='utf-8') as f_out: for line in f_in: # 時間戳提取 time_match = pattern.search(line) if not time_match: continue log_time = time_match.group(1) # 時間條件判斷 if start_time and log_time < start_time: continue # 關(guān)鍵字匹配 if keyword in line: f_out.write(line) # 使用示例 filter_logs('app.log', 'error_logs.txt', 'ERROR', '2023-08-01 12:00:00')
2、CSV數(shù)據(jù)清洗(處理缺失值)
import csv def clean_csv(input_file, output_file, default_value='N/A'): """ 清洗CSV文件:處理空值并保存新文件 """ with open(input_file, 'r', newline='', encoding='utf-8') as f_in, \ open(output_file, 'w', newline='', encoding='utf-8') as f_out: reader = csv.DictReader(f_in) writer = csv.DictWriter(f_out, fieldnames=reader.fieldnames) writer.writeheader() for row in reader: cleaned_row = { key: value if value.strip() != '' else default_value for key, value in row.items() } writer.writerow(cleaned_row) # 使用示例 clean_csv('dirty_data.csv', 'cleaned_data.csv', default_value='0')
3、大文件分塊讀?。▋?nèi)存優(yōu)化)
def process_large_file(file_path, chunk_size=1024*1024): # 默認(rèn)1MB塊 """ 分塊讀取大文件,避免內(nèi)存溢出 """ with open(file_path, 'r', encoding='utf-8') as f: while True: chunk = f.read(chunk_size) if not chunk: break # 在此處處理數(shù)據(jù)塊(例如:計數(shù)、分析等) yield chunk # 使用示例(統(tǒng)計文件行數(shù)) line_count = 0 for chunk in process_large_file('huge_file.log'): line_count += chunk.count('\n') print(f"總行數(shù): {line_count}")
4、配置文件解析(JSON/YAML)
import json import yaml # 需要安裝pyyaml: pip install pyyaml def load_config(config_path): """ 自動識別JSON/YAML配置文件并加載 """ config_path = Path(config_path) if not config_path.exists(): raise FileNotFoundError("配置文件不存在") with open(config_path, 'r', encoding='utf-8') as f: if config_path.suffix == '.json': return json.load(f) elif config_path.suffix in ('.yaml', '.yml'): return yaml.safe_load(f) else: raise ValueError("不支持的配置文件格式") # 使用示例 config = load_config('app_config.yaml') print(config['database']['host'])
5、文件監(jiān)控(實(shí)時處理新內(nèi)容)
import time def tail_file(file_path, interval=1): """ 模擬Linux tail -f 功能,實(shí)時監(jiān)控文件新增內(nèi)容 """ with open(file_path, 'r', encoding='utf-8') as f: # 移動到文件末尾 f.seek(0, 2) while True: line = f.readline() if not line: time.sleep(interval) continue yield line # 使用示例(監(jiān)控日志并報警) for new_line in tail_file('app.log'): if 'CRITICAL' in new_line: send_alert(f"發(fā)現(xiàn)關(guān)鍵錯誤: {new_line}")
6、多文件合并(歸并處理)
from pathlib import Path def merge_csv_files(input_dir, output_file): """ 合并目錄下所有CSV文件(假設(shè)結(jié)構(gòu)相同) """ input_dir = Path(input_dir) csv_files = list(input_dir.glob('*.csv')) with open(output_file, 'w', newline='', encoding='utf-8') as f_out: header_written = False for csv_file in csv_files: with open(csv_file, 'r', newline='', encoding='utf-8') as f_in: reader = csv.reader(f_in) header = next(reader) if not header_written: csv.writer(f_out).writerow(header) header_written = True for row in reader: csv.writer(f_out).writerow(row) # 使用示例 merge_csv_files('daily_reports', 'combined_report.csv')
總結(jié)
到此這篇關(guān)于Python學(xué)習(xí)教程之文件操作詳解的文章就介紹到這了,更多相關(guān)Python文件操作詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Python實(shí)現(xiàn)U盤數(shù)據(jù)自動拷貝
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)U盤數(shù)據(jù)自動拷貝,即當(dāng)電腦上有U盤插入時自動復(fù)制U盤內(nèi)的所有內(nèi)容,希望對大家有所幫助2025-02-02python mqtt 客戶端的實(shí)現(xiàn)代碼實(shí)例
這篇文章主要介紹了python mqtt 客戶端代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09Python用20行代碼實(shí)現(xiàn)批量摳圖功能
在日常的工作和生活中,我們經(jīng)常會遇到需要摳圖的場景,即便是只有一張圖片需要摳,也會摳得我們不耐煩。本文將為大家分享一個20行代碼就能實(shí)現(xiàn)是批量摳圖,需要的可以參考一下2022-05-05Python設(shè)計模式中的狀態(tài)模式你了解嗎
這篇文章主要為大家詳細(xì)介紹了Python設(shè)計模式中的狀態(tài)模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02Python中的chr()函數(shù)與ord()函數(shù)解析
這篇文章主要介紹了Python中的chr()函數(shù)與ord()函數(shù)解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05對pandas的dataframe繪圖并保存的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄獙andas的dataframe繪圖并保存的實(shí)現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08