Python之文本操作
Python之文本操作
文本文件
文本文件是一種典型的順序文件,其文件的邏輯結(jié)構(gòu)又屬于流式文件。文本文件是指以 ASCII 碼方式(也稱文本方式)存儲的文件,更確切地說,英文、數(shù)字等字符存儲的是 ASCII 碼,而漢字存儲的是機(jī)內(nèi)碼。
文本文件中除了存儲文件有效字符信息(包括能用 ASCII 碼字符表示的回車、換行等信息)外,不能存儲其他任何信息,比如圖片、視頻等等。我們常見的 txt 文件就是文本文件。
Python 的 open 方法用于打開一個(gè)文件,并返回文件對象,在對文件進(jìn)行處理過程都需要使用到這個(gè)函數(shù),如果該文件無法被打開,會拋出異常。
open 方法的語法格式為:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closed=True, opener=None)- file:表示要打開的文件路徑(相對或者絕對路徑);
- mode:表示文件打開模式;
- buffering:用于設(shè)置緩沖;
- encoding:用于設(shè)置編碼格式,一般使用 utf8;
- errors:指明編碼和解碼錯(cuò)誤時(shí)怎么樣處理,適用于文本模式;
- newline:文本模式之下,控制一行的結(jié)束字符;
- closed:傳入的 file 參數(shù)類型;
- opener:自定義打開文件方式。
文件打開模式
mode 參數(shù)的打開模式具體如下表所示:
| r | 以只讀方式打開文件。文件的指針將會放在文件的開頭。這是默認(rèn)模式。 |
| rb | 以二進(jìn)制格式打開一個(gè)文件用于只讀。文件指針將會放在文件的開頭。這是默認(rèn)模式。 |
| r+ | 打開一個(gè)文件用于讀寫。文件指針將會放在文件的開頭。 |
| rb+ | 以二進(jìn)制格式打開一個(gè)文件用于讀寫。文件指針將會放在文件的開頭。 |
| w | 打開一個(gè)文件只用于寫入。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
| wb | 以二進(jìn)制格式打開一個(gè)文件只用于寫入。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
| w+ | 打開一個(gè)文件用于讀寫。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
| wb+ | 以二進(jìn)制格式打開一個(gè)文件用于讀寫。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
| a | 打開一個(gè)文件用于追加。如果該文件已存在,文件指針將會放在文件的結(jié)尾。也就是說,新的內(nèi)容將會被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。 |
| ab | 以二進(jìn)制格式打開一個(gè)文件用于追加。如果該文件已存在,文件指針將會放在文件的結(jié)尾。也就是說,新的內(nèi)容將會被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。 |
| a+ | 打開一個(gè)文件用于讀寫。如果該文件已存在,文件指針將會放在文件的結(jié)尾。文件打開時(shí)會是追加模式。如果該文件不存在,創(chuàng)建新文件用于讀寫。 |
| ab+ | 以二進(jìn)制格式打開一個(gè)文件用于追加。如果該文件已存在,文件指針將會放在文件的結(jié)尾。如果該文件不存在,創(chuàng)建新文件用于讀寫。 |
假設(shè)現(xiàn)在有一個(gè) test.txt 文件,位于 step1 目錄下,我們可以使用下列代碼來打開文件:
f = open("step1/test.txt","r",encoding="utf8") # f就是文件對象,一般情況下,只設(shè)置這3個(gè)參數(shù)關(guān)閉文件 close 函數(shù)
close() 方法用于關(guān)閉一個(gè)已打開的文件。關(guān)閉后的文件不能再進(jìn)行讀寫操作, 否則會觸發(fā) ValueError 錯(cuò)誤。 close() 方法允許調(diào)用多次。
當(dāng) file 對象被引用到操作另外一個(gè)文件時(shí),Python 會自動關(guān)閉之前的 file 對象。 使用 close() 方法關(guān)閉文件是一個(gè)好的習(xí)慣。
f = open("step1/test.txt","r",encoding="utf8")# 進(jìn)行相關(guān)的讀寫操作之后使用 close 函數(shù)關(guān)閉文件f.close()文件對象常用屬性
文件對象常用的屬性主要有 3 個(gè):
-
closed:如果文件已被關(guān)閉返回 True,否則返回 False;
f = open("step/test.txt","r",encoding="utf8")print(f.closed)f.close()print(f.closed)執(zhí)行結(jié)果:
FalseTrue -
mode:返回被打開文件的訪問模式;
f = open("step/test.txt","r",encoding="utf8")print(f.mode)執(zhí)行結(jié)果:
r -
name:返回文件的名稱;
f = open("step/test.txt","r",encoding="utf8")print(f.name)執(zhí)行結(jié)果:
step/test.txt
Python文件之文本文件的隨機(jī)讀寫
隨機(jī)讀寫
使用 read 等順序讀寫函數(shù)時(shí),每次都是從每行的第一個(gè)字符開始讀取,但是,我們不一定每次的需求都是從頭開始讀取。假設(shè)我們有test.txt文件,內(nèi)容如下:
hello world下面我們將介紹隨機(jī)讀取的函數(shù):
-
seek(offset,whence=0):用于移動文件讀取指針到指定位置。offset 表示開始的偏移量,也就是代表需要移動偏移的字節(jié)數(shù);whence 表示要從哪個(gè)位置開始偏移;0 代表從文件開頭開始算起,1 代表從當(dāng)前位置開始算起,2 代表從文件末尾算起。
f = open("test.txt","rb") f.seek(2) # 將讀取指針移動到2的位置 print(f.read())# 移動到文件倒數(shù)第5個(gè)字節(jié),如果要設(shè)置whence參數(shù),文件的打開格式必須為二進(jìn)制模式 f.seek(-5,2) print(f.read()) f.close()執(zhí)行結(jié)果:
b'llo world'b'world' -
seekable():如果文件是可搜索的,則 seekable 方法返回 True,否則返回 False。如果文件允許訪問文件流(例如 seek 方法),則該文件是可搜索的。
-
tell():返回文件的當(dāng)前位置,即文件指針當(dāng)前位置。
f = open("test.txt","r") f.seek(2) print(f.tell()) f.read(1) # 讀取一個(gè)字節(jié)的內(nèi)容print(f.tell()) # 讀取內(nèi)容也會改變指針的位置f.close()執(zhí)行結(jié)果:
23 -
truncate([size]):方法用于截?cái)辔募⒎祷亟財(cái)嗟淖止?jié)長度。指定 size 的話,就從文件的開頭開始截?cái)嘀付ㄩL度,其余內(nèi)容刪除;不指定 size 就從文件開頭開始截?cái)嗟疆?dāng)前位置,其余內(nèi)容刪除。
f = open("test.txt","r+")print(f.truncate(3))print(f.read())f.close()執(zhí)行結(jié)果:
3hel
下面是一個(gè)對讀寫文本文件3種方式的總結(jié):
使用Python讀/寫文本文件
? 使用Python來讀/寫文本需要用到“open”這個(gè)關(guān)鍵字。它的作用是打開一個(gè)文件,并創(chuàng)建一個(gè)文件對象。
? 使用Python打開文件,有兩種寫法。
第1種方式如下:
f = open('文件路徑', '文件操作方式', encoding='utf-8') 對文件進(jìn)行操作 f.close()第2種方式,使用Python的上下文管理器:
with open(‘文件路徑’, ‘文件操作方式’, encoding=‘utf-8’) as f:
對文件進(jìn)行操作
第1種方式需要手動關(guān)閉文件,但是在程序開發(fā)中經(jīng)常會出現(xiàn)忘記關(guān)閉文件的情況。第2種方法不需要手動關(guān)閉文件,只要代碼退出了縮進(jìn),Python就會自動關(guān)閉文件
使用Python讀文本文件
? 使用Python打開一個(gè)文本文件時(shí),首先要保證這個(gè)文件是存在的。在讀文件的時(shí)候,“文件操作方式”這個(gè)參數(shù)可以省略,也可以寫成“r”,也就是read的首字母。
? 文件路徑可以是絕對路徑,也可以是相對路徑。如果是絕對路徑,Linux和Mac OS不能直接使用“~”表示“home目錄”,因?yàn)镻ython不認(rèn)識“~”這個(gè)符號。如果非要使用這個(gè)符號,需要使用Python的“os”模塊,代碼如下:
使用下面的代碼來打開text.txt文件:
with open('text.txt', encoding='utf-8') as f:通過f來讀文件
這里有一個(gè)參數(shù)“encoding”。這個(gè)參數(shù)特別有用,它可以在打開文件的時(shí)候?qū)⑽募D(zhuǎn)換為UTF-8編碼格式,從而避免亂碼的出現(xiàn)。這個(gè)參數(shù)只有Python 3有,在Python 2中使用這個(gè)參數(shù)會報(bào)錯(cuò)。如果文件是在Windows中創(chuàng)建的,并且使用UTF-8打開文件出現(xiàn)了亂碼,可以把編碼格式改為GBK
使用Python寫文本文件
使用Python寫文件也需要先打開文件,使用如下代碼來打開文件:
通過f來寫文件
這里多出來一個(gè)參數(shù)“w”,w是英文write的首字母,意思是以寫的方式打開文件。這個(gè)參數(shù)除了為“w”外,還可以為“a”。它們的區(qū)別在于,如果原來已經(jīng)有一個(gè)new.txt文件了,使用“w”會覆蓋原來的文件,導(dǎo)致原來的內(nèi)容丟失;而使用“a”,則會把新的內(nèi)容寫到原來的文件末尾
二進(jìn)制文件的讀寫
我們學(xué)習(xí)了打開二進(jìn)制文件的方式,比如rb、wb等。假設(shè)我們現(xiàn)在有一個(gè)圖片文件test.png。
with open("test.png","rb") as f: print(f.read()) print(f.read(10)) # 只讀取10個(gè)字節(jié)執(zhí)行結(jié)果(不同的圖片結(jié)果不一致):
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01\x02\x00\x00\x01X\x08\x06\x00\x00\x00\xb8Z\xf2\xc1\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\....'b'\x89PNG\r\n\x1a\n\x00\x00'當(dāng)我們寫入二進(jìn)制文件時(shí),我們只能寫入 bytes 類型的數(shù)據(jù)。
with open("test.png","rb") as f,open("result.png","wb") as fb: data = f.read(10) fb.write(data)代碼運(yùn)行后,在當(dāng)前文件夾中就會創(chuàng)建一個(gè)result.png文件,該文件的內(nèi)容為test.png的前 10 個(gè)字節(jié)。
CSV模塊讀寫文件
csv 模塊
CSV (Comma Separated Values) 是逗號分隔符文本格式,常用于 Excel 和數(shù)據(jù)庫的導(dǎo)入和導(dǎo)出,Python 標(biāo)準(zhǔn)庫的 CSV 模塊提供了讀取和寫入 CSV 格式文件的對象。CSV 以純文本存儲數(shù)和文本。文件的每一行就代表一條數(shù)據(jù),每條記錄包含由逗號分隔一個(gè)或多個(gè)屬性值。
以文本的形式打開 csv 文件如圖 1 所示:
圖 1
以 Excel 的形式打開 csv 文件如圖 2 所示:
圖 2
讀取 csv 文件
假設(shè)我們有一個(gè) test.csv 文件,內(nèi)容如圖 2 所示。
-
以返回列表的形式讀取 csv 文件。
import csv # 導(dǎo)入 csv 模塊 with open("test.csv","r") as f: result = csv.reader(f) # 返回的是一個(gè)迭代器 next(result) # 使用next可以跳過第一行的讀取 print(list(result))執(zhí)行結(jié)果:
[['5.1', '3.5', '1.4', '0.2'], ['4.9', '3', '1.4', '0.2'], ['4.7', '3.2', '1.3', '0.2'], ['4.6', '3.1', '1.5', '0.2'], ['5', '3.6', '1.4', '0.2'], ['5.4', '3.9', '1.7', '0.4'], ['4.6', '3.4', '1.4', '0.3'], ['5', '3.4', '1.5', '0.2'], ['4.4', '2.9', '1.4', '0.2'], ['4.9', '3.1', '1.5', '0.1'], ['5.4', '3.7', '1.5', '0.2'], ['4.8', '3.4', '1.6', '0.2'], ['4.8', '3', '1.4', '0.1'], ['4.3', '3', '1.1', '0.1'], ['5.8', '4', '1.2', '0.2'], ['5.7', '4.4', '1.5', '0.4'], ['5.4', '3.9', '1.3', '0.4'], ['5.1', '3.5', '1.4', '0.3'], ['5.7', '3.8', '1.7', '0.3'], ['5.1', '3.8', '1.5', '0.3'], ['5.4', '3.4', '1.7', '0.2'], ['5.1', '3.7', '1.5', '0.4'], ['4.6', '3.6', '1', '0.2'], ['5.1', '3.3', '1.7', '0.5']] -
以字典的形式讀取 csv 文件。
import csv # 導(dǎo)入 csv 模塊 with open("test.csv","r+") as f: # 使用DictReader創(chuàng)建的reader是一個(gè)字典對象,遍歷后,不包含第一行數(shù)據(jù) result = csv.DictReader(f) for x in result: print(x)執(zhí)行結(jié)果:
OrderedDict([('sepal length (cm)', '5.1'), ('sepal width (cm)', '3.5'), ('petal length (cm)', '1.4'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '4.9'), ('sepal width (cm)', '3'), ('petal length (cm)', '1.4'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '4.7'), ('sepal width (cm)', '3.2'), ('petal length (cm)', '1.3'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '4.6'), ('sepal width (cm)', '3.1'), ('petal length (cm)', '1.5'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '5'), ('sepal width (cm)', '3.6'), ('petal length (cm)', '1.4'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '5.4'), ('sepal width (cm)', '3.9'), ('petal length (cm)', '1.7'), ('petal width (cm)', '0.4')])OrderedDict([('sepal length (cm)', '4.6'), ('sepal width (cm)', '3.4'), ('petal length (cm)', '1.4'), ('petal width (cm)', '0.3')])OrderedDict([('sepal length (cm)', '5'), ('sepal width (cm)', '3.4'), ('petal length (cm)', '1.5'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '4.4'), ('sepal width (cm)', '2.9'), ('petal length (cm)', '1.4'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '4.9'), ('sepal width (cm)', '3.1'), ('petal length (cm)', '1.5'), ('petal width (cm)', '0.1')])OrderedDict([('sepal length (cm)', '5.4'), ('sepal width (cm)', '3.7'), ('petal length (cm)', '1.5'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '4.8'), ('sepal width (cm)', '3.4'), ('petal length (cm)', '1.6'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '4.8'), ('sepal width (cm)', '3'), ('petal length (cm)', '1.4'), ('petal width (cm)', '0.1')])OrderedDict([('sepal length (cm)', '4.3'), ('sepal width (cm)', '3'), ('petal length (cm)', '1.1'), ('petal width (cm)', '0.1')])OrderedDict([('sepal length (cm)', '5.8'), ('sepal width (cm)', '4'), ('petal length (cm)', '1.2'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '5.7'), ('sepal width (cm)', '4.4'), ('petal length (cm)', '1.5'), ('petal width (cm)', '0.4')])OrderedDict([('sepal length (cm)', '5.4'), ('sepal width (cm)', '3.9'), ('petal length (cm)', '1.3'), ('petal width (cm)', '0.4')])OrderedDict([('sepal length (cm)', '5.1'), ('sepal width (cm)', '3.5'), ('petal length (cm)', '1.4'), ('petal width (cm)', '0.3')])OrderedDict([('sepal length (cm)', '5.7'), ('sepal width (cm)', '3.8'), ('petal length (cm)', '1.7'), ('petal width (cm)', '0.3')])OrderedDict([('sepal length (cm)', '5.1'), ('sepal width (cm)', '3.8'), ('petal length (cm)', '1.5'), ('petal width (cm)', '0.3')])OrderedDict([('sepal length (cm)', '5.4'), ('sepal width (cm)', '3.4'), ('petal length (cm)', '1.7'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '5.1'), ('sepal width (cm)', '3.7'), ('petal length (cm)', '1.5'), ('petal width (cm)', '0.4')])OrderedDict([('sepal length (cm)', '4.6'), ('sepal width (cm)', '3.6'), ('petal length (cm)', '1'), ('petal width (cm)', '0.2')])OrderedDict([('sepal length (cm)', '5.1'), ('sepal width (cm)', '3.3'), ('petal length (cm)', '1.7'), ('petal width (cm)', '0.5')])
寫入 csv 文件
-
以元組的方式寫入。
import csvheaders = ["name","age","height"]values = [("小王",18,178),("小張",20,180),("小李",17,166)]with open("test.csv","w",encoding="utf-8",newline="") as f: writer = csv.writer(f) writer.writerow(headers) # 首先寫入第一行 writer.writerows(values) # 寫入values代碼運(yùn)行后,test.csv 的內(nèi)容變更為:
name,age,height 小王,18,178 小張,20,180 小李,17,166 -
以字典的形式寫入。
import csv headers = ["name", "age", "height"] values = [{"name":"小王","age":18,"height":178},{"name":"小王","age":18,"height":178},{"name":"小王","age":18,"height":178}] with open("test.csv","w",encoding="utf-8",newline="") as f: writer = csv.DictWriter(f,headers) # 使用csv.DictWriter()方法,需傳入兩個(gè)參數(shù),第一個(gè)為對象,第二個(gè)為文件的title writer.writeheader() # 使用此方法,寫入表頭 writer.writerows(values)代碼運(yùn)行之后,test.csv 文件的內(nèi)容為:
name,age,height 小王,18,178 小張,20,180 小李,17,166
總結(jié)
以上是生活随笔為你收集整理的Python之文本操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。