本文較長,可以自行選擇需要的觀看
如果你是小白剛學習python不久,你可以添加下我的python學習交流群:725479218。

處理檔案是我們每天最常見的任務之一。 Python具有幾個用于執行檔案操作的内置子產品,例如讀取檔案,移動檔案,擷取檔案屬性等。本文總結了您需要了解的許多功能,以涵蓋Python中最常見的檔案操作和良好做法。
這是您将在本文中看到的子產品/功能圖。 要了解有關每個操作的更多資訊,請繼續閱讀。
打開和關閉檔案
當您要讀取或寫入檔案時,首先要做的就是打開檔案。 Python具有打開的内置函數,該函數打開檔案并傳回檔案對象。 檔案對象的類型取決于打開檔案的模式。 它可以是文本檔案對象,原始二進制檔案和緩沖的二進制檔案。 每個檔案對象都有諸如
read()
和
write()
之類的方法。
該代碼塊中有問題,您能識别出來嗎? 我們将在後面讨論。
Python文檔列出了所有可能的檔案模式。 表中列出了最常見的模式。 一個重要的規則是,任何與w相關的模式都将首先截斷該檔案(如果存在),然後建立一個新檔案。 如果您不想覆寫檔案,請謹慎使用此模式,并盡可能使用附加模式。
上一個代碼塊中的問題是我們隻打開了檔案,但沒有關閉檔案。 在處理檔案時始終關閉檔案很重要。 擁有打開的檔案對象可能會導緻不可預測的行為,例如資源洩漏。 有兩種方法可以確定正确關閉檔案。
1.使用close()
第一種方法是顯式使用
close()
。 一個好的做法是将其放入最後,以便我們可以確定在任何情況下都将關閉該檔案。 它使代碼更加清晰,但另一方面,開發人員應該承擔責任,不要忘記關閉它。
2.使用上下文管理器,将
open(...)
設定為f
第二種方法是使用上下文管理器。 如果您不熟悉上下文管理器,那麼請查閱
Dan Bader
用Python編寫的上下文管理器和
“ with”
語句。 與
open()
一起使用,因為f語句實作
__enter__
和
__exit__
方法來打開和關閉檔案。 此外,它将
try / finally
語句封裝在上下文管理器中,這意味着我們将永遠不會忘記關閉檔案。
這個上下文管理器解決方案是否總是比
close()
更好? 這取決于您在哪裡使用它。 以下示例實作了将50,000條記錄寫入檔案的3種不同方式。 從輸出中可以看到,
use_context_manager_2()
函數與其他函數相比性能極低。 這是因為
with
語句在單獨的函數中,它基本上為每個記錄打開和關閉檔案。 這種昂貴的
I / O
操作會極大地影響性能。
Python作為一門不斷發展與普及的語言,還在不斷更新中。在學習時,建議找一些學習夥伴一起來學習和讨論,效果更佳。如果想學習Python,歡迎加入Python學習交流群(627012464),一起督促,一起學習。裡面有開發工具,很多幹貨和技術資料分享!
讀寫檔案
打開檔案後,您必須要讀取或寫入檔案。檔案對象提供了三種讀取檔案的方法,分别是
read()
,
readline()
和
readlines()
。
預設情況下,
read(size = -1)
傳回檔案的全部内容。如果檔案大于記憶體,則可選參數
size
可以幫助您限制傳回的字元(文本模式)或位元組(二進制模式)的大小。
readline(size = -1)
傳回整行,最後包括字元\ n。如果size大于0,它将從該行傳回最大字元數。
readlines(hint = -1)
傳回清單中檔案的所有行。可選參數
hint
表示如果傳回的字元數超過了hint,則将不傳回任何行。
在這三種方法中,
read()
和
readlines()
的記憶體效率較低,因為預設情況下,它們以字元串或清單形式傳回完整的檔案。一種更有效的記憶體疊代方式是使用
readline()
并使其停止讀取,直到傳回空字元串。空字元串“”表示指針到達檔案末尾。
在編寫方面,有兩種方法
write()
和
writelines()
。 顧名思義,
write()是
寫一個字元串,而
writelines()
是寫一個字元串清單。 開發人員有責任在末尾添加\ n。
如果您将文本寫入特殊的檔案類型(例如
JSON
或
csv
),則應在檔案對象頂部使用Python内置子產品
json
或
csv
。
在檔案内移動指針
當我們打開檔案時,我們得到一個指向特定位置的檔案處理程式。 在r和w模式下,處理程式指向檔案的開頭。 在一種模式下,處理程式指向檔案的末尾。
tell()
和
seek()
當我們從檔案中讀取時,指針将移動到下一個讀取将開始的位置,除非我們告訴指針移動。 您可以使用2種方法來做到這一點:
tell()
和
seek()
。
tell()
以檔案開頭的位元組數/字元數的形式傳回指針的目前位置。
seek(offset,whence = 0)
将處理程式移到一個位置,
offset
字元距離
wherece
。 地點可以是:
- 0:從檔案開頭
- 1:從目前位置開始
- 2:從檔案末尾開始
在文本模式下,
wherece
僅應為0,偏移應≥0。
了解檔案狀态
作業系統上的檔案系統可以告訴您許多有關檔案的實用資訊。 例如,檔案的大小,建立和修改的時間。 要在Python中擷取此資訊,可以使用os或pathlib子產品。 實際上,os和pathlib之間有很多共同之處。 pathlib是比os更面向對象的子產品。
作業系統
擷取完整狀态的一種方法是使用
os.stat(“ test.txt”)
。 它傳回具有許多統計資訊的結果對象,例如
st_size
(檔案大小,以位元組為機關),
st_atime
(最新通路的時間戳),
st_mtime
(最新修改的時間戳)等。
您也可以使用
os.path
單獨擷取統計資訊。
路徑庫
擷取完整狀态的另一種方法是使用
pathlib.Path(“ text.txt”.stat())
它傳回與
os.stat()
相同的對象。
在以下各節中,我們将比較
os
和
pathlib
的更多方面。
複制,移動和删除檔案
Python有許多内置子產品來處理檔案移動。 在您信任Google傳回的第一個答案之前,您應該意識到,不同的子產品選擇會導緻不同的性能。 一些子產品将阻塞線程,直到檔案移動完成,而其他子產品則可能異步執行。
關閉
shutil是用于移動,複制和删除檔案和檔案夾的最著名的子產品。 它提供了4種僅複制檔案的方法。
copy()
,
copy2()
和
copyfile()
。
copy()
與
copy2()
:
copy2()
與
copy()
非常相似。 不同之處在于
copy2()
還複制檔案的中繼資料,例如最近的通路時間,最近的修改時間。 但是根據Python文檔,由于作業系統的限制,即使
copy2()
也無法複制所有中繼資料。
copy()
與
copyfile()
:
copy()
将新檔案的權限設定為與原始檔案相同,但是copyfile()不會複制其權限模式。 其次,
copy()
的目标可以是目錄。 如果存在同名檔案,則将其覆寫,否則,将建立一個新檔案。 但是,
copyfile()
的目的地必須是目标檔案名。
os
os子產品具有一個
system()
函數,允許您在子
shell
中執行指令。 您需要将該指令作為參數傳遞給
system()
。 這與在作業系統上執行的指令具有相同的效果。 為了移動和删除檔案,您還可以在
os
子產品中使用專用功能。
異步複制/移動檔案
到目前為止,解決方案始終是同步的,這意味着如果檔案很大并且需要更多時間移動,則程式可能會被阻止。 如果要使程式異步,則可以使用
threading
,
multiprocessing
或
subprocess
子產品使檔案操作在單獨的線程或單獨的程序中運作。
搜尋檔案
複制和移動檔案後,您可能需要搜尋與特定模式比對的檔案名。 Python提供了許多内置函數供您選擇。
glob
glob
子產品根據
Unix shell
使用的規則查找與指定模式比對的所有路徑名。 它支援通配符,例如*?。 []。
glob.glob(“ *。csv”)
搜尋目前目錄中所有具有csv擴充名的檔案。 使用glob子產品,還可以在子目錄中搜尋檔案。
os
os子產品是如此強大,以至于它基本上可以執行檔案操作。 我們可以簡單地使用os.listdir()列出目錄中的所有檔案,并使用
file.endswith()
和
file.startswith()
來檢測模式。 如果要周遊目錄,請使用
os.walk()
。
pathlib
pathlib
具有與
glob
子產品類似的功能。 也可以遞歸搜尋檔案名。 與以前的基于os的解決方案相比,
pathlib
具有更少的代碼,并且提供了更多的面向對象的解決方案。
播放檔案路徑
使用檔案路徑是我們執行的另一項常見任務。 它可以擷取檔案的相對路徑和絕對路徑。 它也可以連接配接多個路徑并找到父目錄等。
相對路徑和絕對路徑
os和pathlib都提供了擷取檔案或目錄的相對路徑和絕對路徑的功能。
聯接 路徑
這是我們可以獨立于環境連接配接os和pathlib中的路徑的方式。 pathlib使用斜杠建立子路徑。
擷取父目錄
dirname()
是在os中擷取父目錄的函數,而在
pathlib
中,您可以僅使用
Path()
。parent來擷取父檔案夾。
作業系統 路徑庫
最後但并非最不重要的一點是,我想簡要介紹一下
os
和
pathlib
。 如Python文檔所述,
pathlib
是比
os
更面向對象的解決方案。 它将每個檔案路徑表示為适當的對象,而不是字元串。 這給開發人員帶來了很多好處,例如,使連接配接多個路徑變得更加容易,在不同的作業系統上更加一緻,并且可以直接從對象通路方法。
我希望本文可以提高您處理檔案的效率。