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