本文較長(zhǎng)骨宠,可以自行選擇需要的觀看
如果你是小白剛學(xué)習(xí)python不久,你可以添加下我的python學(xué)習(xí)交流群:725479218相满。
處理文件是我們每天最常見的任務(wù)之一层亿。 Python具有幾個(gè)用于執(zhí)行文件操作的內(nèi)置模塊,例如讀取文件立美,移動(dòng)文件匿又,獲取文件屬性等。本文總結(jié)了您需要了解的許多功能建蹄,以涵蓋Python中最常見的文件操作和良好做法碌更。
這是您將在本文中看到的模塊/功能圖裕偿。 要了解有關(guān)每個(gè)操作的更多信息,請(qǐng)繼續(xù)閱讀痛单。
打開和關(guān)閉文件
當(dāng)您要讀取或?qū)懭胛募r(shí)击费,首先要做的就是打開文件。 Python具有打開的內(nèi)置函數(shù)桦他,該函數(shù)打開文件并返回文件對(duì)象蔫巩。 文件對(duì)象的類型取決于打開文件的模式。 它可以是文本文件對(duì)象快压,原始二進(jìn)制文件和緩沖的二進(jìn)制文件圆仔。 每個(gè)文件對(duì)象都有諸如read()
和write()
之類的方法。
該代碼塊中有問題蔫劣,您能識(shí)別出來(lái)嗎坪郭? 我們將在后面討論。
Python文檔列出了所有可能的文件模式脉幢。 表中列出了最常見的模式歪沃。 一個(gè)重要的規(guī)則是,任何與w相關(guān)的模式都將首先截?cái)嘣撐募ㄈ绻嬖冢┫铀桑缓髣?chuàng)建一個(gè)新文件沪曙。 如果您不想覆蓋文件,請(qǐng)謹(jǐn)慎使用此模式萎羔,并盡可能使用附加模式液走。
上一個(gè)代碼塊中的問題是我們只打開了文件,但沒有關(guān)閉文件贾陷。 在處理文件時(shí)始終關(guān)閉文件很重要缘眶。 擁有打開的文件對(duì)象可能會(huì)導(dǎo)致不可預(yù)測(cè)的行為,例如資源泄漏髓废。 有兩種方法可以確保正確關(guān)閉文件巷懈。
1.使用close()
第一種方法是顯式使用close()
。 一個(gè)好的做法是將其放入最后慌洪,以便我們可以確保在任何情況下都將關(guān)閉該文件顶燕。 它使代碼更加清晰,但另一方面蒋譬,開發(fā)人員應(yīng)該承擔(dān)責(zé)任割岛,不要忘記關(guān)閉它。
2.使用上下文管理器犯助,將open(...)
設(shè)置為f
第二種方法是使用上下文管理器癣漆。 如果您不熟悉上下文管理器,那么請(qǐng)查閱Dan Bader
用Python編寫的上下文管理器和“ with”
語(yǔ)句剂买。 與open()
一起使用惠爽,因?yàn)閒語(yǔ)句實(shí)現(xiàn)__enter__
和__exit__
方法來(lái)打開和關(guān)閉文件癌蓖。 此外,它將try / finally
語(yǔ)句封裝在上下文管理器中婚肆,這意味著我們將永遠(yuǎn)不會(huì)忘記關(guān)閉文件租副。
這個(gè)上下文管理器解決方案是否總是比close()
更好? 這取決于您在哪里使用它较性。 以下示例實(shí)現(xiàn)了將50,000條記錄寫入文件的3種不同方式用僧。 從輸出中可以看到,use_context_manager_2()
函數(shù)與其他函數(shù)相比性能極低赞咙。 這是因?yàn)?code>with語(yǔ)句在單獨(dú)的函數(shù)中责循,它基本上為每個(gè)記錄打開和關(guān)閉文件。 這種昂貴的I / O
操作會(huì)極大地影響性能攀操。
Python作為一門不斷發(fā)展與普及的語(yǔ)言院仿,還在不斷更新中。在學(xué)習(xí)時(shí)速和,建議找一些學(xué)習(xí)伙伴一起來(lái)學(xué)習(xí)和討論歹垫,效果更佳。如果想學(xué)習(xí)Python颠放,歡迎加入Python學(xué)習(xí)交流群(627012464)排惨,一起督促慈迈,一起學(xué)習(xí)若贮。里面有開發(fā)工具,很多干貨和技術(shù)資料分享痒留!
讀寫文件
打開文件后,您必須要讀取或?qū)懭胛募姥亍N募?duì)象提供了三種讀取文件的方法伸头,分別是read()
,readline()
和readlines()
舷蟀。
默認(rèn)情況下恤磷,read(size = -1)
返回文件的全部?jī)?nèi)容。如果文件大于內(nèi)存野宜,則可選參數(shù)size
可以幫助您限制返回的字符(文本模式)或字節(jié)(二進(jìn)制模式)的大小扫步。
readline(size = -1)
返回整行,最后包括字符\ n匈子。如果size大于0河胎,它將從該行返回最大字符數(shù)。
readlines(hint = -1)
返回列表中文件的所有行虎敦∮卧溃可選參數(shù)hint
表示如果返回的字符數(shù)超過了hint政敢,則將不返回任何行。
在這三種方法中胚迫,read()
和readlines()
的內(nèi)存效率較低喷户,因?yàn)槟J(rèn)情況下,它們以字符串或列表形式返回完整的文件访锻。一種更有效的內(nèi)存迭代方式是使用readline()
并使其停止讀取褪尝,直到返回空字符串∑谌空字符串“”表示指針到達(dá)文件末尾河哑。
在編寫方面,有兩種方法write()
和writelines()
哭懈。 顧名思義灾馒,write()是
寫一個(gè)字符串,而writelines()
是寫一個(gè)字符串列表遣总。 開發(fā)人員有責(zé)任在末尾添加\ n睬罗。
如果您將文本寫入特殊的文件類型(例如JSON
或csv
),則應(yīng)在文件對(duì)象頂部使用Python內(nèi)置模塊json
或csv
旭斥。
在文件內(nèi)移動(dòng)指針
當(dāng)我們打開文件時(shí)容达,我們得到一個(gè)指向特定位置的文件處理程序。 在r和w模式下垂券,處理程序指向文件的開頭花盐。 在一種模式下,處理程序指向文件的末尾菇爪。
tell()
和seek()
當(dāng)我們從文件中讀取時(shí)算芯,指針將移動(dòng)到下一個(gè)讀取將開始的位置,除非我們告訴指針移動(dòng)凳宙。 您可以使用2種方法來(lái)做到這一點(diǎn):tell()
和seek()
熙揍。
tell()
以文件開頭的字節(jié)數(shù)/字符數(shù)的形式返回指針的當(dāng)前位置。seek(offset氏涩,whence = 0)
將處理程序移到一個(gè)位置届囚,offset
字符距離wherece
。 地點(diǎn)可以是:
- 0:從文件開頭
- 1:從當(dāng)前位置開始
- 2:從文件末尾開始
在文本模式下是尖,wherece
僅應(yīng)為0意系,偏移應(yīng)≥0。
了解文件狀態(tài)
操作系統(tǒng)上的文件系統(tǒng)可以告訴您許多有關(guān)文件的實(shí)用信息饺汹。 例如蛔添,文件的大小,創(chuàng)建和修改的時(shí)間。 要在Python中獲取此信息作郭,可以使用os或pathlib模塊陨囊。 實(shí)際上,os和pathlib之間有很多共同之處夹攒。 pathlib是比os更面向?qū)ο蟮哪K蜘醋。
操作系統(tǒng)
獲取完整狀態(tài)的一種方法是使用os.stat(“ test.txt”)
。 它返回具有許多統(tǒng)計(jì)信息的結(jié)果對(duì)象咏尝,例如st_size
(文件大小压语,以字節(jié)為單位),st_atime
(最新訪問的時(shí)間戳)编检,st_mtime
(最新修改的時(shí)間戳)等胎食。
您也可以使用os.path
單獨(dú)獲取統(tǒng)計(jì)信息。
路徑庫(kù)
獲取完整狀態(tài)的另一種方法是使用pathlib.Path(“ text.txt”.stat())
它返回與os.stat()
相同的對(duì)象允懂。
在以下各節(jié)中厕怜,我們將比較os
和pathlib
的更多方面。
復(fù)制蕾总,移動(dòng)和刪除文件
Python有許多內(nèi)置模塊來(lái)處理文件移動(dòng)粥航。 在您信任Google返回的第一個(gè)答案之前,您應(yīng)該意識(shí)到生百,不同的模塊選擇會(huì)導(dǎo)致不同的性能递雀。 一些模塊將阻塞線程,直到文件移動(dòng)完成蚀浆,而其他模塊則可能異步執(zhí)行缀程。
關(guān)閉
shutil是用于移動(dòng),復(fù)制和刪除文件和文件夾的最著名的模塊市俊。 它提供了4種僅復(fù)制文件的方法杨凑。copy()
,copy2()
和copyfile()
摆昧。
copy()
與 copy2()
:copy2()
與copy()
非常相似蠢甲。 不同之處在于copy2()
還復(fù)制文件的元數(shù)據(jù),例如最近的訪問時(shí)間据忘,最近的修改時(shí)間。 但是根據(jù)Python文檔搞糕,由于操作系統(tǒng)的限制勇吊,即使copy2()
也無(wú)法復(fù)制所有元數(shù)據(jù)。
copy()
與 copyfile()
:copy()
將新文件的權(quán)限設(shè)置為與原始文件相同窍仰,但是copyfile()不會(huì)復(fù)制其權(quán)限模式汉规。 其次,copy()
的目標(biāo)可以是目錄。 如果存在同名文件针史,則將其覆蓋晶伦,否則,將創(chuàng)建一個(gè)新文件啄枕。 但是婚陪,copyfile()
的目的地必須是目標(biāo)文件名。
os
os模塊具有一個(gè)system()
函數(shù)频祝,允許您在子shell
中執(zhí)行命令泌参。 您需要將該命令作為參數(shù)傳遞給system()
。 這與在操作系統(tǒng)上執(zhí)行的命令具有相同的效果常空。 為了移動(dòng)和刪除文件沽一,您還可以在os
模塊中使用專用功能。
異步復(fù)制/移動(dòng)文件
到目前為止漓糙,解決方案始終是同步的铣缠,這意味著如果文件很大并且需要更多時(shí)間移動(dòng),則程序可能會(huì)被阻止昆禽。 如果要使程序異步蝗蛙,則可以使用threading
,multiprocessing
或subprocess
模塊使文件操作在單獨(dú)的線程或單獨(dú)的進(jìn)程中運(yùn)行为狸。
搜索文件
復(fù)制和移動(dòng)文件后歼郭,您可能需要搜索與特定模式匹配的文件名。 Python提供了許多內(nèi)置函數(shù)供您選擇辐棒。
glob
glob
模塊根據(jù)Unix shell
使用的規(guī)則查找與指定模式匹配的所有路徑名病曾。 它支持通配符,例如*漾根?泰涂。 []。
glob.glob(“ *辐怕。csv”)
搜索當(dāng)前目錄中所有具有csv擴(kuò)展名的文件逼蒙。 使用glob模塊,還可以在子目錄中搜索文件寄疏。
os
os模塊是如此強(qiáng)大是牢,以至于它基本上可以執(zhí)行文件操作。 我們可以簡(jiǎn)單地使用os.listdir()列出目錄中的所有文件陕截,并使用file.endswith()
和file.startswith()
來(lái)檢測(cè)模式驳棱。 如果要遍歷目錄,請(qǐng)使用os.walk()
农曲。
pathlib
pathlib
具有與glob
模塊類似的功能社搅。 也可以遞歸搜索文件名。 與以前的基于os的解決方案相比,pathlib
具有更少的代碼形葬,并且提供了更多的面向?qū)ο蟮慕鉀Q方案合呐。
播放文件路徑
使用文件路徑是我們執(zhí)行的另一項(xiàng)常見任務(wù)。 它可以獲取文件的相對(duì)路徑和絕對(duì)路徑笙以。 它也可以連接多個(gè)路徑并找到父目錄等捌议。
相對(duì)路徑和絕對(duì)路徑
os和pathlib都提供了獲取文件或目錄的相對(duì)路徑和絕對(duì)路徑的功能委可。
聯(lián)接 路徑
這是我們可以獨(dú)立于環(huán)境連接os和pathlib中的路徑的方式栽连。 pathlib使用斜杠創(chuàng)建子路徑誉己。
獲取父目錄
dirname()
是在os中獲取父目錄的函數(shù),而在pathlib
中谈息,您可以僅使用Path()
缘屹。parent來(lái)獲取父文件夾。
操作系統(tǒng) 路徑庫(kù)
最后但并非最不重要的一點(diǎn)是侠仇,我想簡(jiǎn)要介紹一下os
和pathlib
轻姿。 如Python文檔所述,pathlib
是比os
更面向?qū)ο蟮慕鉀Q方案逻炊。 它將每個(gè)文件路徑表示為適當(dāng)?shù)膶?duì)象互亮,而不是字符串。 這給開發(fā)人員帶來(lái)了很多好處余素,例如豹休,使連接多個(gè)路徑變得更加容易,在不同的操作系統(tǒng)上更加一致桨吊,并且可以直接從對(duì)象訪問方法威根。
我希望本文可以提高您處理文件的效率。