肝!超好懂的 Python 文件读写教程!
(掃碼關(guān)注)
1.文件讀寫(xiě)的流程
1)類比windows中手動(dòng)操作txt文檔,說(shuō)明python中如何操作txt文件?
① windows中手動(dòng)操作txt文件的步驟
找到word文檔
打開(kāi)word文檔
查看(或操作)word文檔中的內(nèi)容
關(guān)閉word文檔
② python操作txt文件的步驟
獲取被打開(kāi)的文件的內(nèi)存對(duì)象,該內(nèi)存對(duì)象又叫做文件句柄
通過(guò)這個(gè)內(nèi)存對(duì)象(文件句柄),來(lái)對(duì)文件進(jìn)行操作(讀取,寫(xiě)入等操作)
關(guān)閉文件
2)什么是文件的內(nèi)存對(duì)象(文件句柄)?
使用python讀取一個(gè)txt文件的時(shí)候,相當(dāng)于把這個(gè)文件從硬盤(pán)上,讀取到了內(nèi)存中。
我們?nèi)绻胍僮鬟@個(gè)文件,是不是先要獲取這個(gè)文件對(duì)象?只有獲取這個(gè)文件對(duì)象后,才能夠真正的去操作這個(gè)文件,不管是讀取文件中的內(nèi)容,還是向文件中寫(xiě)入內(nèi)容。
這個(gè)文件句柄包含了文件的文件名、文件的字符集、文件的大小、文件在硬盤(pán)上的起始位置。
3)演示怎么讀取文件
① 演示如下
f?=?open(r"G:\6Tipdm\file_read_write\yesterday.txt","r",encoding="utf-8") data??=?f.read() print(data[:245]) f.close()結(jié)果如下:
② 一個(gè)很奇怪的現(xiàn)象?
f?=?open(r"G:\6Tipdm\file_read_write\yesterday.txt","r",encoding="utf-8") data??=?f.read() data1?=?f.read() print(data[:245]) print("-------------------------------------") print(data1[:245]) f.close()結(jié)果如下:
問(wèn)題:我們讀取了2遍內(nèi)容,為什么只顯示了一次讀取的結(jié)果呢?對(duì)于上述問(wèn)題,我們用一張圖回答上述問(wèn)題。
通過(guò)上圖我們可以發(fā)現(xiàn),當(dāng)我們操作這個(gè)文件句柄的read()方法去讀取文件的時(shí)候,這個(gè)句柄會(huì)從文件的開(kāi)頭位置1,移動(dòng)到文件的結(jié)束位置2。
如果不做任何操作,讀取完畢之后,句柄就會(huì)停止在2這個(gè)位置。因此當(dāng)我們?cè)俅巫x取文件的時(shí)候,該句柄是從2這個(gè)位置,往后面讀取內(nèi)容。由于后面沒(méi)有任何內(nèi)容,因此第二次讀取為空。
那么,如果我們想要第二次同樣能夠讀取到文件中的內(nèi)容,應(yīng)該怎么辦呢?那么接著往下看。
4)演示怎么寫(xiě)文件
f?=?open(r"G:\6Tipdm\file_read_write\yesterday2.txt","w",encoding="utf-8") f.write("我愛(ài)北京天安門(mén)") f.close()結(jié)果如下:
假如我們?cè)趯?xiě)一句天安門(mén)上太陽(yáng)升,會(huì)出現(xiàn)啥情況呢?
f?=?open(r"G:\6Tipdm\file_read_write\yesterday2.txt","w",encoding="utf-8") f.write("天安門(mén)上太陽(yáng)升") f.write("很好,很好") f.close()結(jié)果如下:
意外發(fā)生:當(dāng)我們?cè)俅螌?xiě)入新的內(nèi)容的時(shí)候,發(fā)現(xiàn)之前寫(xiě)的內(nèi)容不見(jiàn)了,這是為啥呢?這就是我們下面要講述的文件讀寫(xiě)的幾種常見(jiàn)模式。??
2.文件讀寫(xiě)的幾種常見(jiàn)模式(你不清楚的知識(shí)點(diǎn))
1)關(guān)于r+、w+、a+使用說(shuō)明(易錯(cuò)點(diǎn))
當(dāng)我們讀取某個(gè)文件,向文件中寫(xiě)入某些內(nèi)容(覆蓋寫(xiě)),向文件中追加寫(xiě)入某寫(xiě)內(nèi)容時(shí),最好的方式就是分別使用r、w、a這三種模式。對(duì)于這三種模式,要么讀,要么寫(xiě),讀模式就不能寫(xiě),寫(xiě)模式就不能讀。
對(duì)于r+、w+、a+這三種模式,如果你不是特別清楚python文件讀寫(xiě)的原理,就不要輕易使用,因?yàn)闀?huì)出現(xiàn)很多問(wèn)題,下面我們僅演示r+、w+、a+這三種模式。
2)r+模式:可讀可寫(xiě)
對(duì)于這種模式,不管是讀取文件中的內(nèi)容,還是朝文件中寫(xiě)入內(nèi)容。前提條件:文件存在。
#?只讀取文件中的內(nèi)容 f?=?open(r"G:\6Tipdm\file_read_write\yesterday1.txt","r+",encoding="utf-8") data?=?f.read() print(data) f.close()#?朝文件中寫(xiě)入內(nèi)容后,立即讀取,會(huì)出現(xiàn)啥問(wèn)題? f?=?open(r"G:\6Tipdm\file_read_write\yesterday1.txt","r+",encoding="utf-8") f.write("麗麗姑娘")data?=?f.read() print(data) f.close()#?朝文件中寫(xiě)入內(nèi)容后,調(diào)整句柄位置后,再讀取,會(huì)出現(xiàn)啥問(wèn)題? f?=?open(r"G:\6Tipdm\file_read_write\yesterday1.txt","r+",encoding="utf-8") f.write("麗麗姑娘") f.seek(0) data?=?f.read() print(data) f.close()結(jié)果如下:
使用r+模式,當(dāng)只讀文件的時(shí)候,可以讀取到其中的內(nèi)容。
當(dāng)寫(xiě)入內(nèi)容后,立即讀取文件內(nèi)容,發(fā)現(xiàn)什么也讀取不到。這是由于當(dāng)你寫(xiě)入內(nèi)容后,文件句柄會(huì)放在寫(xiě)入內(nèi)容的最后面,因此當(dāng)你立即讀取的時(shí)候,句柄會(huì)從上次內(nèi)容最后的位置,往后面讀,因此讀取為空。
當(dāng)朝文件中寫(xiě)入內(nèi)容后,調(diào)整句柄位置后,再讀取文件中的內(nèi)容,發(fā)現(xiàn)就有了內(nèi)容。這是由于我們使用了f.seek(0)方法,將句柄由內(nèi)容末尾調(diào)整到了內(nèi)容開(kāi)頭,因此就又有了內(nèi)容。
3)w+:可讀可寫(xiě)
#?直接往文件中寫(xiě)入內(nèi)容 f?=?open(r"G:\6Tipdm\file_read_write\yesterday3.txt","w+",encoding="utf-8") f.write("bbbbbb") f.close()#?直接讀取上述文件,看看會(huì)發(fā)生啥問(wèn)題?(特別注意這一步) f?=?open(r"G:\6Tipdm\file_read_write\yesterday3.txt","w+",encoding="utf-8") data?=?f.read() print(data) f.close()#?朝文件中寫(xiě)入內(nèi)容后,立即讀取,又會(huì)發(fā)生什么? f?=?open(r"G:\6Tipdm\file_read_write\yesterday3.txt","w+",encoding="utf-8") f.write("哈哈哈哈哈") data?=?f.read() print(data) f.close()#?朝文件中寫(xiě)入內(nèi)容后,調(diào)整句柄位置后,再讀取,會(huì)發(fā)生什么? f?=?open(r"G:\6Tipdm\file_read_write\yesterday3.txt","w+",encoding="utf-8") f.write("嘿嘿嘿嘿嘿") f.seek(0) data?=?f.read() print(data) f.close()結(jié)果如下:
使用w+模式,當(dāng)我們直接朝文件中寫(xiě)入bbbbbb,毋庸置疑,肯定是可以的。
接著,我們直接讀取這個(gè)文件中的內(nèi)容,奇怪的現(xiàn)象發(fā)生了,什么都讀取不到。這是因?yàn)閣+模式,在進(jìn)行文件讀取的時(shí)候,默認(rèn)是先寫(xiě)再讀。但是我們確實(shí)沒(méi)有寫(xiě)入任何東西呀?這是由于系統(tǒng)默認(rèn)幫我們寫(xiě)入了一個(gè)空值,因此把原有內(nèi)容覆蓋了。所以再當(dāng)我們讀取文件中的內(nèi)容的時(shí)候,發(fā)現(xiàn)讀取為空。
再接著,我們朝文件中,寫(xiě)入內(nèi)容后再立即讀取,這下仍然讀取不到任何內(nèi)容,這又是為什么呢?這是由于我們第一次寫(xiě)入“哈哈哈哈哈哈”的時(shí)候,句柄移動(dòng)到了內(nèi)容最后。當(dāng)我們立即讀取的時(shí)候,句柄從內(nèi)容最后的位置,繼續(xù)朝后面讀,因此啥也沒(méi)有。
最后,當(dāng)朝文件中寫(xiě)入內(nèi)容后,調(diào)整句柄位置后,再讀取文件中的內(nèi)容,發(fā)現(xiàn)就有了內(nèi)容。這是由于我們使用了f.seek(0)方法,將句柄由內(nèi)容末尾調(diào)整到了內(nèi)容開(kāi)頭,因此就又有了內(nèi)容。
4)a+:可讀可寫(xiě)
#?直接朝文件中寫(xiě)入內(nèi)容 f?=?open(r"G:\6Tipdm\file_read_write\yesterday4.txt","a+",encoding="utf-8") f.write("哈哈") f.close()#?直接讀取文件中的內(nèi)容 f?=?open(r"G:\6Tipdm\file_read_write\yesterday4.txt","a+",encoding="utf-8") data?=?f.read() print(data) f.close()#?調(diào)整句柄位置后,再讀取文件中的內(nèi)容 f?=?open(r"G:\6Tipdm\file_read_write\yesterday4.txt","a+",encoding="utf-8") f.seek(0) data?=?f.read() print(data) f.close()結(jié)果如下:
使用a+模式,朝文件中寫(xiě)入內(nèi)容,毋庸置疑,肯定是沒(méi)問(wèn)題的。
接著,當(dāng)我們讀取上述文件中的內(nèi)容,會(huì)發(fā)現(xiàn)什么也讀取不到。這是由于,使用r+模式打開(kāi)文件,文件句柄默認(rèn)放在內(nèi)容的最后面,因此你直接讀取其中的內(nèi)容,什么也沒(méi)有。
最后,在讀取文件中內(nèi)容之前,我們使用了f.seek(0)方法,將句柄由內(nèi)容末尾調(diào)整到了內(nèi)容開(kāi)頭,再次讀取文件中的內(nèi)容,發(fā)現(xiàn)就有了內(nèi)容。
3.read、readline、readlines的區(qū)別
1)read()方法的使用說(shuō)明
f?=?open(r"G:\6Tipdm\file_read_write\test.txt","r",encoding="utf-8") data?=?f.read() print(type(data)) print(data) f.close()結(jié)果如下:
2)readline()方法的使用說(shuō)明
f?=?open(r"G:\6Tipdm\file_read_write\test.txt","r",encoding="utf-8") data?=?f.readline() print(type(data)) print(data) f.close()f?=?open(r"G:\6Tipdm\file_read_write\test.txt","r",encoding="utf-8") for?i?in?range(3):data?=?f.readline()print(data) f.close()結(jié)果如下:
去掉每一行末尾的換行符:
f?=?open(r"G:\6Tipdm\file_read_write\test.txt","r",encoding="utf-8") for?i?in?range(3):data?=?f.readline().strip()print(data) f.close()結(jié)果如下:
3)readlines()方法的使用說(shuō)明
f?=?open(r"G:\6Tipdm\file_read_write\test.txt","r",encoding="utf-8") data?=?f.readlines() print(type(data)) print(data) f.close()結(jié)果如下:
4.對(duì)于一個(gè)10G的大文件,怎么高效的查看文件中的內(nèi)容呢?
1)相關(guān)說(shuō)明
當(dāng)我們讀取文件中的內(nèi)容,相當(dāng)于是把寫(xiě)在硬盤(pán)上的東西,讀取到內(nèi)存中。不管你是使用read()或者readlines()一次性讀取到到內(nèi)存中,還是使用readline()一行行的將整個(gè)內(nèi)容讀取到內(nèi)存中,如果文件很大,都將會(huì)耗用很大的內(nèi)存。同時(shí),從硬盤(pán)讀取文件內(nèi)容到內(nèi)存中,也會(huì)很慢。
因此,有沒(méi)有一種高效的方式?既讓我們看到了文件中的內(nèi)容,又不會(huì)占用內(nèi)存呢?下面我們將進(jìn)行說(shuō)明。
2)操作說(shuō)明
f?=?open(r"G:\6Tipdm\file_read_write\yesterday.txt","r",encoding="utf-8") for?line?in?f:print(line.strip())部分截圖如下:
上述方式中,f相當(dāng)于一個(gè)迭代器,我們使用for循環(huán)迭代f中元素。每循環(huán)一次,就相當(dāng)于讀取一行到內(nèi)存中,并記住這一次讀取到的位置。當(dāng)進(jìn)行下次迭代的時(shí)候,上一次讀取到內(nèi)存中的內(nèi)容,就會(huì)被銷毀了,當(dāng)前內(nèi)存中讀取的就是第二行的內(nèi)容。當(dāng)進(jìn)行第三次循環(huán)的時(shí)候,內(nèi)存中第二行的內(nèi)容也會(huì)被銷毀,此時(shí)內(nèi)存中只會(huì)保存第三行的內(nèi)容,這樣依次進(jìn)行下去。直到最后一次循環(huán),讀取最后一行的內(nèi)容,此時(shí),內(nèi)存中保留的也只是最后一行的內(nèi)容。
迭代器有一個(gè)特性:每次進(jìn)行迭代的時(shí)候,就會(huì)記住當(dāng)前讀取的位置。當(dāng)進(jìn)行下一次迭代的時(shí)候,前面的內(nèi)容會(huì)被銷毀掉,在內(nèi)存中只會(huì)保留當(dāng)前循環(huán)得到的內(nèi)容。
- End -
精 彩 文 章?肝!計(jì)算機(jī)網(wǎng)絡(luò)基礎(chǔ)知識(shí)總結(jié)程序員必備網(wǎng)站之一:No Design你離黑客的距離,就差這20個(gè)神器了付費(fèi)?是不可能的!20行Python代碼實(shí)現(xiàn)一款永久免費(fèi)PDF編輯工具最后說(shuō)一個(gè)題外話,相信大家有不少人開(kāi)通了視頻號(hào)。小詹也開(kāi)通了一個(gè)視頻號(hào),會(huì)分享互聯(lián)網(wǎng)那些事、讀書(shū)心得與副業(yè)經(jīng)驗(yàn),歡迎各位掃描下方二維碼關(guān)注。總結(jié)
以上是生活随笔為你收集整理的肝!超好懂的 Python 文件读写教程!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 肝!计算机网络基础知识总结
- 下一篇: 微软推出 Pylance,改善 VS C