新聞中心
今天小編給大家分享一下Python文件處理方法實例代碼分析的相關(guān)知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
創(chuàng)新互聯(lián)公司執(zhí)著的堅持網(wǎng)站建設(shè),小程序定制開發(fā);我們不會轉(zhuǎn)行,已經(jīng)持續(xù)穩(wěn)定運營十載。專業(yè)的技術(shù),豐富的成功經(jīng)驗和創(chuàng)作思維,提供一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造品牌,攜手廣大客戶,共同發(fā)展進步。
打開文件
讓我們從最基本的文件讀取示例開始。假設(shè)我在與我的代碼文件相同的目錄中有一個文件,名為journal1.txt
.
打開文件的標(biāo)準(zhǔn)方式是使用內(nèi)置open()
函數(shù),默認從io
模塊導(dǎo)入。
file = open("journal1.txt", 'r') for line in file: print(line) file.close()
open()
函數(shù)接受許多參數(shù),用于以高級方式與文件交互,但大多數(shù)情況下,你只需要前兩個參數(shù)
第一個參數(shù)file
接受一個字符串,該字符串包含打開的文件的絕對路徑或相對路徑。這是唯一嚴格要求的參數(shù)。
第二個參數(shù)mode
接受一個指示文件模式的字符串。如果未指定,將使用'rt'
,這意味著它將文件作為文本讀取。模式'r'
實際上是相同的,因為文本模式 ( t
) 是默認行為的一部分。
我可以用這行來代替,得到同樣的行為。。。
file = open("journal1.txt")
但我個人更喜歡明確指出我是在閱讀(r
),寫作(w
),還是你有什么。
從open()
返回的所有“文件”對象都是可迭代的。對于文本文件,返回一個TextIOWrapper
對象。在上面的示例中,我遍歷TextIOWrapper
對象文件中的行,并打印出每一行。
處理完文件后,我需要使用file.close()
關(guān)閉它。 重要的是不要依賴垃圾收集器為你關(guān)閉文件,因為這種行為既不能保證也不方便實現(xiàn)。此外,Python 不能保證在調(diào)用.close()
之前完成對文件的寫入。
運行該代碼,至少在我的情況下,不會打印出journal1.txt
內(nèi)容:
Could this be where all missing things are found? Magic Hair Only for the Pure of Heart Not naturally occurring? Could result in minor gravity anomalies!
上下文管理器
在實踐中,始終記住調(diào)用close()
可能是一件非常痛苦的事情,尤其是當(dāng)你考慮到打開文件時可能出現(xiàn)的錯誤時。值得慶幸的是,還有一種更簡潔的方法:上下文管理器!
上下文管理器由Python 中的with
語句定義。我可以使用以下語法重寫我之前的代碼:
with open("journal1.txt", 'r') as file: for line in file: print(line)
調(diào)用open()
函數(shù),如果成功,則生成的TextIOWrapper
對象存儲在 中file
,并且可以在with
語句的主體中使用。一旦控制離開with
語句,file.close()
就會被隱式調(diào)用;你永遠不必記得調(diào)用它!
我們將在下一章更深入地介紹這一點。
文件模式
該文檔提到了幾種可用于open()
的模式:
r
打開文件進行讀取(默認)。w
打開或創(chuàng)建文件以首先寫入、刪除(截斷)其內(nèi)容。a
打開或創(chuàng)建要寫入的文件,但追加到末尾而不是截斷。x
創(chuàng)建并打開一個新文件進行寫入;它無法打開現(xiàn)有文件。+
打開文件進行讀寫(見下表)。t
以文本模式處理文件(默認)。b
以二進制模式處理文件。
這些模式標(biāo)志可以組合在一起。例如,在二進制模式下,a+b允許寫入和讀取,其中寫入附加到文件末尾。
+標(biāo)志始終與另一標(biāo)志組合。當(dāng)與r
結(jié)合使用時,它添加了a
的功能,但它從文件開頭開始(不截斷)。當(dāng)與w
、a
或x
組合時,它也允許讀取。
使用此表可以最好地理解不同標(biāo)志的行為:
| r r+ w w+ a a+ x x+ ---------------------|---------------------------------- allow read | ? ? ? ? ? allow write | ? ? ? ? ? ? ? create new file | ? ? ? ? ? ? open existing file | ? ? ? ? ? ? erase file contents | ? ? allow seek | ? ? ? ? ? position at start | ? ? ? ? ? ? position at end | ? ?
讀
我們可以使用read()
,readline()
或者readlines()
函數(shù)以文本模式讀取文件,也可以直接迭代
當(dāng)然,這需要使用適當(dāng)?shù)奈募J綐?biāo)志打開文件進行讀?。ㄕ垍㈤啞拔募J健辈糠郑?。如果需要檢查對象文件是否可以讀取,請使用file.readable()
函數(shù)。
讓我們對比一下讀取文件的三種方式:
read()
read()
函數(shù)將文件的全部內(nèi)容作為一個長字符串讀取。
with open("journal1.txt", 'r') as file: contents = file.read() print(contents) # Could this be where all missing things are found? # Magic Hair Only for the Pure of Heart # Not naturally occurring? # Could result in minor gravity anomalies!
或者,你可以告訴read()
從文件流中讀取的最大字符數(shù):
with open("journal1.txt", 'r') as file: contents = file.read(20) print(contents) # Could this be where
readline()
readline()
函數(shù)的行為與read()
完全相同,只是它在遇到換行符時停止讀取。換行符包含在返回的字符串中。
with open("journal1.txt", 'r') as file: contents = file.readline() print(contents) # Could this be where all missing things are found?
與read()
一樣,你可以指定要讀取的最大字符數(shù):
with open("journal1.txt", 'r') as file: contents = file.readline(20) print(contents) # Could this be where
readlines()
readlines()
函數(shù)以字符串列表的形式返回整個文件,每個字符串為一行。
with open("journal1.txt", 'r') as file: contents = file.readlines() for c in contents: print(c) # Could this be where all missing things are found? # # Magic Hair Only for the Pure of Heart # # Not naturally occurring? # # Could result in minor gravity anomalies! #
你會注意到每一行都包含換行符。我們可以通過在每個字符串上調(diào)用.strip()
函數(shù)來刪除它。
with open("journal1.txt", 'r') as file: contents = file.readlines() for c in contents: print(c.strip()) # Could this be where all missing things are found? # Magic Hair Only for the Pure of Heart # Not naturally occurring? # Could result in minor gravity anomalies!
你還可以通過指定最大字符數(shù)來限制從文件中讀取的內(nèi)容。然而,與以前不同的是,這不是硬性限制。相反,一旦到目前為止從所有行讀取的字符總數(shù)超過了指定的限制,則只會讀取當(dāng)前行的其余部分。
通過比較read()
和readlines()
可以最好地理解這一點。首先,我將閱讀限制為60個字符:
with open("journal1.txt", 'r') as file: contents = file.read(60) print(contents) # Could this be where all missing things are found? # Magic Hair
將readlines()
與使用 60 個字符的“提示”進行比較:
with open("journal1.txt", 'r') as file: contents = file.readlines(60) for c in contents: print(c.strip()) # Could this be where all missing things are found? # Magic Hair Only for the Pure of Heart
在第二個示例中,讀取前兩行的全部內(nèi)容,但不再讀取。
與其他兩個函數(shù)不同,readlines()
總是讀取整行。
迭代
如你之前所見,我們可以直接迭代文件:
with open("journal1.txt", 'r') as file: for line in file: print(line) # Could this be where all missing things are found? # Magic Hair Only for the Pure of Heart # Not naturally occurring? # Could result in minor gravity anomalies!
這在功能上與以下內(nèi)容相同:
with open("journal1.txt", 'r') as file: for line in file.readlines(): print(line)
兩者的區(qū)別在于第一種方法,直接迭代,是惰性的,而第二種方法在迭代內(nèi)容之前首先讀取整個文件。
寫
使用write()
orwritelines()
函數(shù),我們可以以幾乎相同的方式寫入文件。
這需要打開文件進行寫入(參見“文件模式”部分)。file.writable()
函數(shù)可用于檢查file
對象是否可寫。
在本節(jié)的示例中,我將在底部的注釋中顯示文件內(nèi)容。
write()
write()
函數(shù)將給定的行寫入文件。
我可以使用write()
將整個多行字符串寫入一個名為journal3.txt
的新文件,如下所示:
entry = """If you go on enough road trips chances are, you've seen a certain bumper sticker: WHAT IS THE MYSTERY SHACK? """ with open("journal3.txt", 'x') as file: file.write(entry) # If you go on enough road trips # chances are, you've seen a # certain bumper sticker: # WHAT IS THE MYSTERY SHACK? #
只要journal3.txt
不存在,它將使用給定的內(nèi)容創(chuàng)建。
我可以使用w
文件模式覆蓋journal3.txt
的全部內(nèi)容:
with open("journal3.txt", 'w') as file: file.write("GNOMES\nWEAKNESS?\n") # GNOMES # WEAKNESS? #
注意:注意你的文件模式!
w
并將w+
刪除文件的全部內(nèi)容。使用a
或a+
寫入文件末尾。
我可以使用a
文件模式附加到文件中:
with open("journal3.txt", 'a') as file: file.write("leaf blowers\n") # GNOMES # WEAKNESS? # leaf blowers #
write()
函數(shù)返回一個整數(shù),表示寫入的字符數(shù)。
writelines()
writelines()
函數(shù)將字符串列表寫入文件。
lines = [ "Finally back safe and sound\n", "from one of the weirdest days\n", "at Gravity Falls.\n" ] with open("journal3.txt", 'w') as file: file.writelines(lines) # Finally back safe and sound # from one of the weirdest days # at Gravity Falls. #
與 withwrite()
不同,writelines()
函數(shù)只返回None
。
搜索
file.seek()
函數(shù)允許你在文件對象file
中逐個字符地來回移動。處理文本流時,它接受一個參數(shù):一個正整數(shù),表示要移動到的新位置,表示為從開頭開始的字符數(shù)。
除了改變位置之外,該file.seek()
函數(shù)還將返回一個表示文件中新絕對位置的整數(shù)。你可用file.tell()
來獲取該文件的當(dāng)前位置。
r+
文件模式最好與函數(shù)seek()
一起使用,盡管它可以與除 a
和a+
之外的任何其他文件模式一起使用。
我將首先使用seek()
函數(shù)來讀取journal1.txt
文件的一部分:
with open("journal1.txt", 'r') as file: file.seek(50) contents = file.read(5) print(contents) # MAGIC
我將編寫journal3.txt
文件的新初始版本:
with open("journal3.txt", 'w') as file: file.write("FLOATING EYEBALLS") # FLOATING EYEBALLS
我可以使用該r+
模式更改此文件的一部分。
注意:
write()
命令將始終覆蓋文件的現(xiàn)有內(nèi)容,除非你追加到末尾。要將文本非破壞性地插入文件,通常最好將整個內(nèi)容作為字符串(或列表)讀取,編輯字符串,然后將其寫回。
在這里,我將用“NONSENSE!”替換“EYEBALLS”這個詞:
with open("journal3.txt", 'r+') as file: file.seek(9) file.write("NONSENSE!") # FLOATING NONSENSE!
打開文件后,我從頭移動到第 9 個字符,然后write()
是新數(shù)據(jù)。
用二進制搜索
當(dāng)你以二進制模式 ( b
) 打開文件時,你可以以更動態(tài)的方式在文件中移動,使用兩個參數(shù)而不是一個參數(shù):
offset
:字符移動的距離(可以是負數(shù))whence
: 計算偏移量的位置:0
表示文件的開始位置(默認),1
表示當(dāng)前位置,2
表示文件的結(jié)束位置。
不幸的是,使用whence
參數(shù)不適用于以文本模式打開的文件。
文件錯誤
與處理文件相關(guān)的四個最常見錯誤如下:
FileNotFoundError
r
和r+
模式要求文件在打開之前存在。否則,將引發(fā)FileNotFoundError
錯誤:
try: with open("notreal.txt", 'r') as file: print(file.read()) except FileNotFoundError as e: print(e)
FileExistsError
x
和x+
文件模式專門用于創(chuàng)建新文件。如果文件已存在,將引發(fā)FileExistsError
錯誤:
try: with open("journal3.txt", 'x+') as file: print(file.read()) except FileExistsError as e: print(e)
UnsupportedOperation
每當(dāng)你嘗試讀取僅打開用于寫入的文件或?qū)懭雰H打開用于讀取的文件時都會引發(fā)錯誤io.UnsupportedOperation
:
import io try: with open("journal3.txt", 'w') as file: print(file.read()) except io.UnsupportedOperation as e: print(e) try: with open("journal3.txt", 'r') as file: file.write('') except io.UnsupportedOperation as e: print(e)
換行符的問題
一些聰明的讀者會記得,雖然UNIX使用\n
作為行分隔符,但Windows使用\r\n
。當(dāng)我們讀寫文件時,這肯定很重要,對吧?
事實上,Python 在幕后為我們抽象了這一點。無論操作系統(tǒng)如何,在以文本模式寫入文件時始終用作行分隔符!\n
文件路徑
到目前為止,我只使用了與代碼相同文件夾中的文件,但這很少是我們想要的!我們需要能夠構(gòu)建文件路徑。
問題是,所有系統(tǒng)上的文件路徑都不相同。UNIX風(fēng)格的系統(tǒng),如macOS和Linux,使用UNIX文件路徑約定,而Windows使用完全不同的方案。我們的解決方案必須對兩者都有效,這意味著硬路徑不是一個選項。
為了解決這個問題,Python 提供了兩個模塊:os
和pathlib
。
創(chuàng)建路徑
Python實際上提供了多個用于構(gòu)建路徑的類,這取決于你的特定需求。但是,在大多數(shù)情況下,你應(yīng)該只使用pathlib.Path
。
假設(shè)我想在當(dāng)前用戶的主文件夾中創(chuàng)建一個名為.dead_simple_python
的特殊目錄,然后將文件寫入該位置。我會這樣做:
首先,我創(chuàng)建一個Path()
對象,指向最終所需的目錄(而不是文件)。
在Path()
構(gòu)造函數(shù)中,我將路徑的每個部分作為單獨的字符串傳遞。我可以使用類方法Path.home()
來獲取用戶目錄的路徑。
from pathlib import Path import os file_path = Path(Path.home(), ".dead_simple_python")
接下來,我將使用file_path.exists()
檢查路徑是否已經(jīng)存在。如果它不存在,我將使用os.makedirs
函數(shù)用于創(chuàng)建路徑中缺少的任何目錄:
if not file_path.exists(): os.makedirs(file_path)
最后,我可以將文件名添加到已經(jīng)擁有的路徑對象中,然后打開該文件進行寫入:
file_path = file_path.joinpath("journal4.txt") with file_path.open('w') as file: lines = [ "If you've ever taken a road trip \n", "through the Pacific Northwest, you've \n", "probably seen a bumper sticker for a \n", "place called Gravity Falls.\n" ] file.writelines(lines)
你會注意到我使用了file_path.open('w')
,而不是open(file_path, 'w')
。從技術(shù)上講,兩者的作用完全相同,盡管成員函數(shù)是首選。
相對路徑
open("journal1.txt")
之所以有效,是因為它是一個相對路徑,從執(zhí)行代碼的目錄開始。
如果我的代碼所在的目錄中有一個journals/
目錄,我可以使用它:
from pathlib import Path file_path = Path("journals", "journal1.txt") with file_path.open('r') as file: print(file.read())
只要我不是從絕對路徑開始,比如由Path.home()
生成的路徑,路徑都是相對的。
但是如果我想向上移動一個目錄而不是向下移動呢?你可能會嘗試使用..
,但正如你可能猜到的,這并不能保證在所有操作系統(tǒng)上都是可移動的。相反,我可以使用os.pardir
移動到上一個目錄。
想象一下,我們有一個如下所示的目錄結(jié)構(gòu):
example ├── code │ └── read_file.py └── journals └── journal1.txt
如果在path_relative2/code
運行python read_file.py
,我可以通過以下方式訪問journal1.txt
:
from pathlib import Path import os file_path = Path(os.pardir, "journals", "journal1.txt") with file_path.open('r') as file: print(file.read())
以上就是“Python文件處理方法實例代碼分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
本文題目:Python文件處理方法實例代碼分析
網(wǎng)站URL:http://fisionsoft.com.cn/article/gocodd.html