Python 以优雅的姿势 操作文件
Python 以優雅的姿勢 操作文件
文章目錄
- Python 以優雅的姿勢 操作文件
- open() 方法🎏
- 文件打開模式📌
- 使用 with 語句💡
- 創建文件
- 讀取文件
- 增加內容(末尾)
- 修改文件內容(重點)🧬
- 刪除文件
- 刪除文件夾
- 擴展:利用 OS 模塊
- 擴展:文件編碼知識
- 相關博客😏
open() 方法🎏
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)參數如下:
-
file:文件路徑(絕對路徑或者相對路徑),如果直接寫文件名的話那就是 相對路徑
-
mode:為字符串參數,用于指定打開文件的模式,默認值是 “r”,也就是讀取模式,其余模式參考下面內容
-
buffering:可選的整數參數,用于設置緩沖策略,若為 0 以切換緩沖關閉(僅允許在二進制模式下),1選擇行緩沖(僅在文本模式下),大于1的整數以指示固定大小的塊緩沖區的大小(單位:字節),如果沒有給出參數,默認緩沖策略的工作方式如下:
- 二進制文件以固定大小的塊進行緩沖;使用啟發式方法選擇緩沖區的大小,嘗試確定底層設備的“塊大小”或使用 io.DEFAULT_BUFFER_SIZE。在大多數系統上,緩沖區的長度通常為 4096 或 8192 字節。
- “交互式”文本文件( isatty() 返回 True 的文件)使用行緩沖。其他文本文件使用上述策略用于二進制文件。
-
encoding:指定用于解碼或編碼文件時 所 編碼的名稱,只在文本模式下使用,默認值(默認編碼類型)是根據你的操作系統平臺決定的,Windows系統是默認國產的 GBK編碼,Liunx 、Macos 系統 為默認 UTF-8 編碼,這也是為什么在Windos平臺上打開utf-8編碼文件時報錯的原因,這里建議 好習慣 encoding=”utf-8"
-
errors:可選字符串參數,指定如何處理編碼和解碼錯誤,不能在二進制模式下使用
- strict :如果存在編碼錯誤,會引發 ValueError 報錯,默認值 None 具有相同的效果
- ignore :忽略錯誤,但忽略編碼錯誤可能會導致數據丟失,可能會在一些嵌入式環境中使用
- replace :會將替換標記(例如 ‘?’ )插入有錯誤數據的地方
-
newline:控制 universal newlines (通用換行符)模式如何生效(它僅適用于文本模式),如果 newline 為 None,則啟用通用換行模式,輸入中的行可以以 ‘\n’,’\r’ 或 ‘\r\n’ 結尾,這些行被Python翻譯成 ‘\n’ ,簡單來說,就是以什么為判斷內容下一行的依據,windos默認約定為 “\r\n” , Unix 為 “\n”,MacOS 為 “\r”
-
closefd:如果 closefd 是 False 并且給出了文件描述符而不是文件名,那么當文件關閉時,底層文件描述符將保持打開狀態;如果給出文件名則 必須為 True(默認值,否則將引發錯誤
-
opener:設置自定義開啟器,通過使用參數( file,flags )調用 opener 獲得文件對象的基礎文件描述符,開啟器必須返回一個打開的文件描述符。
文件打開模式📌
| r | 以 只讀 方式打開文件(默認) | 正常讀取 | 報錯 FileNotFoundError |
| rb | 以 二進制格式 打開文件 用于 讀取 | 正常讀取 | 報錯 FileNotFoundError |
| w | 以 只寫 方式打開文件 | 清空原有內容從頭開始寫入 | 創建新文件進行寫入 |
| wb | 以 二進制 方式打開文件 用于 寫入 | 清空原有內容從頭開始寫入 | 創建新文件進行寫入 |
| a | 以 追加 方式打開文件 | 新的內容將會被寫入到已有內容末尾 | 創建新文件進行寫入 |
| ab | 以 二進制 方式打開文件 用于 追加 | 新的內容將會被寫入到已有內容末尾 | 創建新文件進行寫入 |
| x | 排它性創建 寫模式 | 創建新文件進行寫入 | 報錯 FileExistsError |
| b | 不單獨使用,二進制模式 | ~ | ~ |
| t | 不單獨使用,文本模式(默認) | ~ | ~ |
| U | 通用換行模式(Python3 已棄用) | ~ | ~ |
以 內容數據 類型為參考的話,Python 區分二進制 和 文本,那么又分為文本模式 和 二進制模式
1) 文本模式
在不指定文件模式時,默認模式為 “r”,打開用于讀取文本,與 “rt” 是一樣的。
文本模式下,文件內容返回為 字符串,使用 “r”,“w” 等模式時,與 后面加 “t” 相同,“r” = “rt”
2) 二進制模式
二進制模式下,返回的內容為 bytes 對象,不進行任何解碼
在Python 中創建 圖片、視頻等文件時,就需要用到 二進制模式 寫入數據內容。
其實,用的最多的還是原生的文件打開模式,r 和 w
在大部分情況下,這兩種模式相互配合使用就已經夠了
使用 with 語句💡
在使用 open() 內置函數 操作文件時,得記得在操作結束后加上一句 f.close()
每次操作完都得加上 f.close() ,顯得有些麻煩,且如果在操作完忘記加上這一句話,還會造成資源一直占用的問題
于是,這里 推薦使用 with 語句 來提升編寫代碼的效率
普通寫法
f = open("中文.txt", "r", encoding="utf-8") data = f.read() print(data) f.close()使用 with 語句
with open("中文.txt", "r", encoding="utf-8") as f:data = f.read()print(data)優點:
- 提升代碼閱讀性
- 減少代碼冗余,免去 f.close() 步驟,同時也防止忘記關閉文件調用
接下來的代碼,我將統一使用 with 語句演示
創建文件
創建文件,常用的 文件打開模式是 “w”,當然也可以使用 “x” 模式,前提是你所指定的目錄下沒有這個文件
只是創建一個空白文件的話 可以這么寫
with open("文件.txt", "w", encoding="utf-8") as f_w:pass創建多個文件 可以配合循環
for i in range(1, 5):with open(f"文件_{i}.txt", "w", encoding="utf-8") as f_w:pass創建文件 并且 寫入內容
with open(f"文件.txt", "w", encoding="utf-8") as f_w:f_w.write("hello word")讀取文件
讀取文件,用到的 文件打開模式是 “r”
-
.read(size = -1)*
讀取全部- size : 指定讀取的字節數, 默認值-1表示讀取整個文件
with open(f"中文.txt", "r", encoding="utf-8") as f_w:data = f_w.read() # 讀取所有內容print(data)
讀取全部內容利用 size 參數 在特點場合下有妙用
with open(f"中文.txt", "r", encoding="utf-8") as f_w:while True:data = f_w.read(10) # 每次只讀取10個字節if data:print(data)else:break -
.readline(size = -1)
讀取一行- size : 指定中讀取的字節數, 默認值-1表示讀取一行內容, 用法與上面 .read() 相同
with open(f"中文.txt", "r", encoding="utf-8") as f_w:data = f_w.readline()print(data)
讀取一行一行一行方式讀取 全部內容
with open(f"中文.txt", "r", encoding="utf-8") as f_w:while True:data = f_w.readline()if not data:breakprint(data)# 還可以直接循環文件對象實現 with open(f"中文.txt", "r", encoding="utf-8") as f_w:for line in f_w:print(line)
.readline(size = -1)
讀取所有行,并返回列表,每一行為列表中的一個值
增加內容(末尾)
對文件內容進行追加,用到的 文件打開模式是 “a”
追加的內容會寫在文件末尾
with open("中文.txt", "w", encoding="utf-8") as f_w: # 創建初始文件f_w.write("我是第一行內容\n")with open("中文.txt", "a", encoding="utf-8") as f_a: # 追加文件內容f_a.write("我是追加的內容")這個模式用在寫簡單的 程序運行 日志 上
修改文件內容(重點)🧬
需要使用到兩種 文件打開模式 進行配合,先讀(“r”)后寫(“w”)
原理:
很簡單,就是先將 內容讀取 到內存,然后對讀取到的數據進行修改、增加、刪除等操作,再重新寫入到新文件中,再把舊文件替換成新文件,在編輯過程未結束的情況下 產生的新文件可以理解為 臨時文件,此時尚未與舊文件替換
這種修改方式其實很常見,拿我們常用的 word 文檔來看
在平時編輯word文檔時,會發現在其相對路徑下會生成一個隱藏文件,命名通常是以~$開頭,后面跟著文件名
替換文件
那么,在py中怎么替換文件呢?
這就需要用到 os 標準庫模塊下的 os.replace()
os.replace("新文件", "舊文件")根據以上原理,Py實現
temp_name = r"~$" file_name = "中文.txt" with open(f"{temp_name}{file_name}", "w", encoding="utf-8") as f_w:with open(file_name, "r", encoding="utf-8") as f_r:data = f_r.read()data = data.replace("內容", "nei_rong") # 替換操作data += "我是再加上的內容\n" # 增加內容 f_w.write(data)os.replace(f"{temp_name}{file_name}", file_name) # 替換文件刪除文件
這里需要用到 os 標準庫模塊
file_path = "" if os.path.isfile(file_path):os.remove(file_path) # 只能刪除文件 非文件夾注意:只能刪除文件,非文件夾,否則會出現 OSError 錯誤
刪除文件夾
需要注意的是,文件夾分兩種,一種是空文件夾,另外一種則是文件夾中有內容的 非空文件夾
-
空文件夾:
dir_path = "" if not os.listdir(dir_path):os.rmdir(dir_path)
利用 os 標準庫模塊
os.rmdir() 刪除指定路徑的目錄,文件夾必須為空如果刪除非空文件夾,會出現 OSError 錯誤
-
非空文件夾:
方法一:(推薦)
path = "" if os.path.isdir(path):shutil.rmtree(path) # 刪除非空文件夾
利用 shutil 標準庫模塊
shutil.rmtree() 刪除一個完整的目錄樹方法二:
for b, d, f in os.walk(path, topdown=False): # 一定要設置 topdown 參數為False,從里層開始 for file_n in f:os.remove(os.path.join(b, file_n)) for dir_p in d:dir_p = os.path.join(b, dir_p)if not os.listdir(dir_p):os.rmdir(dir_p) else:os.rmdir(path)
還是使用回 os 標準庫模塊中的功能,但這個方法比較繁瑣
擴展:利用 OS 模塊
OS 模塊是個利器,操作文件時 有 OS 可以做出更厲害的操作
導入os模塊
1) 判斷文件是否存在
os.path.isfile() # 判斷路徑是否為文件根據文件是否存在決定寫入模式
file_path = "" # 文件目錄 if os.path.isfile(file_path):print("文件存在")with open(file_path, "a", encoding="urf-8") as f_a:f_a.write("寫入內容") # 追加文件中的內容 else:print("文件不存在")with open(file_path, "w", encoding="utf-8") as f_w:f_w.write("寫入內容")2) 拼接路徑
os.path.join() # 把目錄和文件名合成一個路徑 path = os.path.join("路徑一", "路徑二")3) 獲取根路徑
適用于當前所運行的 py文件
BASE_DIR = os.path.dirname(__file__) # 獲取當前Py 根目錄4) 判斷文件夾是否存在
os.path.isdir() # 判斷路徑是否為目錄如果文件夾不存在,則創建文件夾并在此文件夾內創建文件
BASE_DIR = os.path.dirname(__file__) # 獲取當前Py 根目錄 dir_path = [os.path.join(BASE_DIR, "我是文件夾"), ] # 文件夾路徑 file_path = os.path.join(dir_path[0], "我是文件.txt") # 文件目錄def judg_isdir(funx):"""文件夾初始化裝飾器"""def inner(*args, **kwargs):for d in dir_path:if not os.path.isdir(d): # 如果文件夾不存在則創建os.mkdir(d)return funx(*args, **kwargs)return inner@judg_isdir def mydir():if os.path.isfile(file_path): # 如果文件存在print("文件存在")with open(file_path, "a", encoding="urf-8") as f_a:f_a.write("寫入內容") # 追加文件中的內容else:print("文件不存在")with open(file_path, "w", encoding="utf-8") as f_w:f_w.write("寫入內容")mydir()擴展:文件編碼知識
1) ASCII
ASCII (American Standard Code for Information Interchange,美國信息交換標準代碼)是基于拉丁 字母 的一套編碼,主要用于顯示現代英語和其他西歐語言,是最通用的信息交換標準,并等同于國際標準 ISO/IEC 646
ASCII 第一次以規范標準的類型發表是在1967年,最后一次更新則是在1986年,到目前為止共定義了128個字符
由于計算機是美國人發明的,因此最早只有 ASCII 被編碼到計算機里,大小寫英文字母、數字和一些符號
ASCII 碼對照表
大寫字母 A 對應的編碼是65,小寫字母 a 對應編碼是97,數字 1 對應的編碼是 49
這些都可以通過 Python內置函數 ord() 進行查看
2) GB2312 & GBK
GB2312 和 GBK 都為 國產編碼,GB2312 于1980年 最早發布
GBK 是 GB2312 的升級版,加入更多字符,向下與 GB 2312 編碼兼容國產編碼,一直用到現在,Windos中文平臺 默認編碼依舊是 GBK
可以在 命令提示符 中的屬性 看到Windos平臺 默認的編碼
3) Unicode
Unicode 是 ISO(國際標誰化組織)制定的可以容納世界上所有文字和符號的字符編碼,所以又俗稱 萬國碼、統一碼,解決了 傳統的字符編碼方案的局限(簡單來說:每個國家都有自己一套的編碼標準,如果跨國辦公或者跨國產品,很容易出現各個國家編碼不相通,造成亂碼,在當時萬國碼沒出來之前,各國之間的編碼可謂是戰國時期,亂碼現象很常見)
特點:
-
Unicode 為每種語言中的每個字符設定了統一并且唯一的二進制編碼,以滿足跨語言、跨平臺進行文本轉換、處理、閱讀,極大改善了不同國家之間的信息傳遞
-
可以跟各種語言的編碼自由轉換,兼容性很強,比如說用 gbk編碼 的文本 ,可以轉成Unicode
-
容納世界上所有文字和符號的字符編碼
4) UTF-8
Unicode 是 字符集,UTF-8 是 編碼規則
UTF-8 就是 Unicode 的實現方式,對unicode字符集進行編碼的一種編碼方式
在計算機內存中,使用Unicode編碼,當需要保存到硬盤或者需要傳輸的時候,就轉換為UTF-8編碼
具體流程:編輯文本時,從文件讀取 UTF-8 字符轉換為 Unicode 字符到內存里,進行編輯操作,編輯完成后,再把內存中的 Unicode 字符 轉換為UTF-8 字符 存儲到文件里
注意:utf-8 不能直接于 gbk 轉換,需要有 Unicode 作為中間人 過渡,這是為什么 在WIndows平臺上 打開utf-8文本文件時容易出現亂碼的原因
此外 還有UTF-16,UTF-32
對比表
依據 出現時間 排序
| ASCII | 1967年 | 最早誕生編碼,英語和西歐語言 | 一字節 |
| GB2312 | 1980年 | 國產簡體中文編碼,兼容 ASCII 碼 | 兩字節 |
| Unicode | 1991年 | 國際統一標準字符集,俗稱萬國碼 | 兩字節 |
| GBK | 1995年 | GB2312升級版,支持繁體,加入更多字符 | 兩字節 |
| UTF-8 | 1992年 | 不定長編碼 | 1 - 3 字節 |
相關博客😏
- Python 到底是 線程快 還是 進程快
總結
以上是生活随笔為你收集整理的Python 以优雅的姿势 操作文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: diy副屏黑屏求解答
- 下一篇: Python小练习 - python编写