摘要:如果該文件已存在,文件的初始指針在文件的結(jié)尾。文件中只有一句話十步殺一人,千里不留行。關(guān)閉文件如果用來(lái)打開文件的話就不用管關(guān)閉文件的操作了,因?yàn)橐呀?jīng)幫你完成了這一步,否則必須在處理文件之后加上關(guān)閉文件的操作
讀取文件的操作步驟
有一道腦筋急轉(zhuǎn)彎,問(wèn)把大象裝進(jìn)冰箱的步驟,答案很簡(jiǎn)單,打開冰箱、把大象推進(jìn)去、關(guān)閉冰箱。這就是一個(gè)處理問(wèn)題的思路,我們對(duì)文件的操作和這個(gè)一樣,第一步:打開文件;第二部:處理文件(讀取或者寫入);第三部關(guān)閉文件,怎么樣?其實(shí)很簡(jiǎn)單吧,下面我們就來(lái)詳細(xì)說(shuō)說(shuō)文件的操作。
打開文件open(file, mode="r", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
打開文件要使用open()函數(shù),()內(nèi)涉及的參數(shù)在初期階段我們只需要知道三個(gè)參數(shù)即可,那就是file、mode、和encoding
file首先是文件名,類型是字符串,要包含路徑,如果要打開的文件和當(dāng)前文件在同一個(gè)目錄下則可以省略路徑(相對(duì)路徑).
mode然后是打開文件的模式,格式是:mode="模式", 這里的"mode="可以省略,直接寫模式即可,如果不指定模式則默認(rèn)為r,具體的模式如下:
這里引入一個(gè)偽名詞——指針,想象一下當(dāng)你在word中編輯文本時(shí)有個(gè)光標(biāo)吧?你可以把指針想象成那個(gè)光標(biāo),光標(biāo)在哪里你對(duì)文件的所有操作就從哪里開始。
r 只讀。文件的初始指針在文件的開頭。這是默認(rèn)模式。 rb 只讀的二進(jìn)制格式。文件的初始指針在文件的開頭。 r+ 讀寫。文件的初始指針在文件的開頭。 rb+ 讀寫的二進(jìn)制格式。文件的初始指針在文件的開頭。 w 只寫。如果該文件已存在則打開文件,清空文件內(nèi)容。如果該文件不存在,則創(chuàng)建新文件。 wb 只寫的二進(jìn)制格式。如果該文件已存在則打開文件,清空文件內(nèi)容。如果該文件不存在,創(chuàng)建新文件。 w+ 寫讀。如果該文件已存在則打開文件,清空文件內(nèi)容。如果該文件不存在,創(chuàng)建新文件。 wb+ 寫讀的二進(jìn)制格式。如果該文件已存在則打開文件,清空文件內(nèi)容。如果該文件不存在,創(chuàng)建新文件。 a 追加寫。如果該文件存在,文件的初始指針在文件的結(jié)尾。新的內(nèi)容將會(huì)被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。 ab 追加寫的二進(jìn)制格式。如果該文件存在,文件的初始指針在文件的結(jié)尾。新的內(nèi)容將會(huì)被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。 a+ 追加寫讀。如果該文件已存在,文件的初始指針在文件的結(jié)尾。文件打開時(shí)會(huì)是追加模式。如果該文件不存在,創(chuàng)建新文件用于讀寫。 ab+ 追加寫讀的二進(jìn)制格式。如果該文件已存在,文件的初始指針在文件的結(jié)尾。如果該文件不存在,創(chuàng)建新文件用于讀寫。encoding
第三個(gè)參數(shù)是文件的編碼(非二進(jìn)制格式時(shí)使用),編碼的設(shè)置必須與要打開的文件的編碼一致,否則會(huì)報(bào)錯(cuò),也就是說(shuō)源文件是用什么編碼寫入的,你打開時(shí)就得用什么編碼打開。
處理文件我們來(lái)舉一個(gè)出錯(cuò)的例子,要實(shí)現(xiàn)的操作是打開文件名為“test”的文件,原文件編碼為utf-8,而我們打開時(shí)使用了gbk編碼。
文件中只有一句話:十步殺一人,千里不留行。
代碼如下:
file = open("test","r",encoding="gbk") content = file.read() print(content) file.close()
這里說(shuō)明以下,open函數(shù)返回的結(jié)果是一個(gè)文件對(duì)象,所以要用一個(gè)變量接收一下(file),
這樣我們就可以方便地使用這個(gè)對(duì)象的方法了,比如file.read(),file.write,file.flush()等等
read()是文件對(duì)象的一個(gè)方法,作用是讀取指定的字符數(shù),如果未指定則默認(rèn)讀取所有內(nèi)容
但是上面的代碼執(zhí)行后會(huì)報(bào)錯(cuò),下面是報(bào)錯(cuò)信息,大意是gbk編碼無(wú)法解碼(文件打開的過(guò)程實(shí)際就是解碼的過(guò)程)
--------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last)in () 4 #這里說(shuō)明以下,open函數(shù)返回的結(jié)果是一個(gè)文件對(duì)象,所以要用一個(gè)變量接收一下(file),這樣我們就可以方便地使用這個(gè) 5 #對(duì)象的方法了,比如file.read(),file.write,file.flush()等等 ----> 6 content = file.read()#read()是文件對(duì)象的一個(gè)方法,作用是讀取指定的字符數(shù),如果未指定則默認(rèn)讀取所有內(nèi)容 7 print(content) 8 file.close() UnicodeDecodeError: "gbk" codec can"t decode byte 0xad in position 4: illegal multibyte sequence
解決的辦法很簡(jiǎn)單,把編碼方式改為utf-8即可,因?yàn)閘inux系統(tǒng)默認(rèn)是utf-8編碼,所以編碼也可以省略不寫,又因?yàn)槲覀冎皇且x取下文件,所以模式為r,而默認(rèn)模式為r,也可以省略不寫。
所以代碼就變成了下面的樣子:
file = open("test") content = file.read() print(content) file.close() 輸出為: 十步殺一人,千里不留行
方法read()中也可以添加數(shù)字參數(shù),作用是指定讀取的字符數(shù),不管是漢字還是字母一個(gè)字符對(duì)應(yīng)一個(gè)字母或者漢字,這里一定要和字節(jié)區(qū)分開,例子如下:
file = open("test") content = file.read(3) print(content) file.close() 輸出為: 十步殺
我們之前使用的打開文件的方式比較麻煩,因?yàn)楸仨氁诮Y(jié)束時(shí)寫關(guān)閉文件的語(yǔ)句,這里介紹一種簡(jiǎn)便的方法,格式是:
with open() as file_name: 操作代碼......
使用這種方法的好處是不用寫關(guān)閉文件的語(yǔ)句,with 和as是關(guān)鍵字,記住格式即可.
接下來(lái)我們創(chuàng)建一個(gè)二進(jìn)制格式的文件
with open("二進(jìn)制","wb") as file: file.write("十步殺一人,千里不留行".encode("utf8"))
因?yàn)槲覀兇蜷_文件的方式是以二進(jìn)制格式打開的,那么在寫入文件時(shí)就要寫入二進(jìn)制格式的字符串,但是對(duì)于”十步殺一人,千里不留行“這個(gè)字符串的二進(jìn)制格式是什么呢?我們并不知道,所以我們使用.encode(utf8)來(lái)把這個(gè)字符串轉(zhuǎn)換成二進(jìn)制格式。實(shí)際上我們通過(guò)另外一段代碼是可以知道這個(gè)字符串對(duì)應(yīng)的二進(jìn)制格式的,代碼如下:
print("十步殺一人,千里不留行".encode("utf8")) 輸出的二進(jìn)制格式(表現(xiàn)形式為16進(jìn)制,為什么?因?yàn)槎M(jìn)制太長(zhǎng)了啊!!!)為: b"xe5x8dx81xe6xadxa5xe6x9dx80xe4xb8x80xe4xbaxbaxefxbcx8cxe5x8dx83xe9x87x8cxe4xb8x8dxe7x95x99xe8xa1x8c"
在實(shí)際中我們當(dāng)然不可能寫這么長(zhǎng)的東西,所以我們使用.encode("utf8")來(lái)轉(zhuǎn)化。轉(zhuǎn)化時(shí)我們使用了utf-8的編碼方式。
在這里說(shuō)明一下為什么要編碼,想弄清楚這件事就要明白計(jì)算機(jī)的存儲(chǔ)原理。
簡(jiǎn)單地講,文件在計(jì)算機(jī)中都是以二進(jìn)制格式存儲(chǔ)的,對(duì)于計(jì)算機(jī)來(lái)講只有兩個(gè)數(shù)字有意義,那就是0和1,也就是二進(jìn)制,而不同的0和1的組合代表不同的含義(編碼不同),比如在gbk編碼下一個(gè)漢字由兩個(gè)字節(jié)表示,也就是16位二進(jìn)制數(shù)(16個(gè)0和1的組合),而在utf-8編碼下一個(gè)漢字由3個(gè)字節(jié)表示,也就是24位二進(jìn)制數(shù)(24個(gè)0和1的組合),而我們現(xiàn)在要給計(jì)算機(jī)存儲(chǔ)的就是0和1的組合,那么在讀取文件或者轉(zhuǎn)化字符串時(shí),如果你不告訴計(jì)算機(jī)你使用的是哪種編碼的話,計(jì)算機(jī)怎么可能知道這些0和1的組合代表什么含義呢?所以從計(jì)算機(jī)取出數(shù)據(jù)或者把普通字符串轉(zhuǎn)化成二進(jìn)制格式時(shí)你必須告訴計(jì)算機(jī)你使用的是什么編碼方式。
在本例中使用utf-8編碼,所以在字符串后面加上.encode(utf8)
那么為什么平時(shí)可以直接寫入普通字符串呢?那是因?yàn)樵谟胦pen()函數(shù)打開文件的時(shí)候就已經(jīng)指定了編碼方式。
形象地解釋:open函數(shù)相當(dāng)于打開了一種通道,平時(shí)打開時(shí)都是用某種編碼的方式打開的,所以我們?cè)趯懭雰?nèi)容時(shí)不必管它以什么編碼進(jìn)入通道的(因?yàn)樵趏pen函數(shù)里面就已經(jīng)指定了編碼方式)
而當(dāng)open函數(shù)使用二進(jìn)制格式打開時(shí)(就是帶b的模式),這個(gè)通道就沒(méi)有指定編碼方式,通道里面只有二進(jìn)制,所以此時(shí)往通道里面放入非二進(jìn)制格式內(nèi)容的話就需要指定一種編碼方式。除非你直接在file.write()函數(shù)中直接寫二進(jìn)制,但是人類是不可能記住那么多二進(jìn)制組合所代表的含義的。
然后我們來(lái)讀取一下上面創(chuàng)建的名字為“二進(jìn)制”的這個(gè)文件
with open("二進(jìn)制","rb") as file: print("不指定解碼方式時(shí)的結(jié)果:",file.read())
如果我們?cè)谧x取時(shí)不指定解碼方式,那么輸出的結(jié)果就是下面這種人類無(wú)法理解的奇怪的東西(實(shí)際上它是用16進(jìn)制表示的二進(jìn)制)
不指定解碼方式時(shí)的結(jié)果: b"xe5x8dx81xe6xadxa5xe6x9dx80xe4xb8x80xe4xbaxbaxefxbcx8cxe5x8dx83xe9x87x8cxe4xb8x8dxe7x95x99xe8xa1x8c"
所以我們?cè)谧x取時(shí)也要指定編碼:
with open("二進(jìn)制","rb") as file: content = file.read() print("指定解碼方式后的結(jié)果:",content.decode("utf-8")) 指定解碼方式后的結(jié)果: 十步殺一人,千里不留行
其他的在讀取時(shí)可能用到的方法:
readline()讀取一行,如果里面添加了參數(shù)n,則會(huì)讀取n個(gè)字符(我覺(jué)得這是個(gè)bug,貌似沒(méi)什么卵用) readlines()讀取所有內(nèi)容,結(jié)果返回一個(gè)列表,元素由每一行組成。 tell()會(huì)輸出當(dāng)前指針的位置,注意,該位置是以字節(jié)來(lái)計(jì)算的,不是字符 seek()重新指定指針位置。
使用readlines()并不是一個(gè)好方法,因?yàn)槭且淮涡詫⑽募甲x取到內(nèi)存中,如果文件較大時(shí)則造成內(nèi)存溢出,實(shí)際中使用下面的方法,系統(tǒng)會(huì)自動(dòng)生成一個(gè)迭代器,用迭代的方法把需要的數(shù)據(jù)取出來(lái)。
with open("libai") as f: for i in f: #這里的i實(shí)際就是迭代后的每一行,用for循環(huán)的方式從文件對(duì)象中取出來(lái),取一行讀一行,節(jié)省內(nèi)存 print(i)
趙客縵胡纓,吳鉤霜雪明。銀鞍照白馬,颯沓如流星。 十步殺一人,千里不留行。事了拂衣去,深藏身與名。 閑過(guò)信陵飲,脫劍膝前橫。將炙啖朱亥,持觴勸侯嬴。 三杯吐然諾,五岳倒為輕。眼花耳熱后,意氣素霓生。 救趙揮金錘,邯鄲先震驚。千秋二壯士,烜赫大梁城。 縱死俠骨香,不慚世上英。誰(shuí)能書閣下,白首太玄經(jīng)。關(guān)閉文件
如果用with open() 來(lái)打開文件的話就不用管關(guān)閉文件的操作了,因?yàn)镻ython已經(jīng)幫你完成了這一步,否則必須在處理文件之后加上關(guān)閉文件的操作:file_name.close()
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/42554.html
摘要:今天我們來(lái)討論下下如何實(shí)現(xiàn)打開文件修改文件關(guān)閉文件的操作本文采用逐行解釋的方法。這樣,我們就實(shí)現(xiàn)了文件的修改。 今天我們來(lái)討論下python下如何實(shí)現(xiàn):打開文件—修改文件——關(guān)閉文件的操作 本文采用逐行解釋的方法。 思路: 第一步:把文件讀取出來(lái)第二部:再用w模式寫入到新文件第三部:把原文件刪除,并且把新文件重命名回原文件這樣就實(shí)現(xiàn)了文件的修改操作 我們先來(lái)看看原文件的內(nèi)容 with ...
摘要:它則是以行為單位返回字符串,也就是每次讀一行,依次循環(huán),如果不限定,直到最后一個(gè)返回的是空字符串,意味著到文件末尾了。 讀文件 在某個(gè)文件夾下面建立了一個(gè)文件,名曰:130.txt,并且在里面輸入了如下內(nèi)容: learn python http://qiwsir.github.io qiwsir@gmail.com f = open(123.txt) #打開已經(jīng)存在的文件,此文件在當(dāng)前...
摘要:可以對(duì)文件進(jìn)行查看創(chuàng)建等功能,可以對(duì)文件內(nèi)容進(jìn)行添加修改刪除,且所使用到的函數(shù)在為,在同時(shí)支持和,但是在系列移除了函數(shù)。在及以后,又支持同時(shí)對(duì)多個(gè)文件的上下文進(jìn)行管理,即原文鏈接 Python可以對(duì)文件進(jìn)行查看、創(chuàng)建等功能,可以對(duì)文件內(nèi)容進(jìn)行添加、修改、刪除,且所使用到的函數(shù)在Python3.5.x為open,在Python2.7.x同時(shí)支持file和open,但是在3.5.x系列移除...
摘要:其實(shí),迭代器遠(yuǎn)遠(yuǎn)不止上述這么簡(jiǎn)單,下面我們隨便列舉一些,在中還可以這樣得到迭代對(duì)象中的元素。 跟一些比較牛X的程序員交流,經(jīng)常聽到他們嘴里冒出一個(gè)不標(biāo)準(zhǔn)的英文單詞,而loop、iterate、traversal和recursion如果不在其內(nèi),總覺(jué)得他還不夠牛X。當(dāng)讓,真正牛X的絕對(duì)不會(huì)這么說(shuō)的,他們只是說(shuō)循環(huán)、迭代、遍歷、遞歸,然后再問(wèn)這個(gè)你懂嗎?。哦,這就是真正牛X的程序員。不過(guò),...
摘要:解析配置模塊之詳解基本的讀取配置文件直接讀取文件內(nèi)容得到所有的,并以列表的形式返回得到該的所有得到該的所有鍵值對(duì)得到中的值,返回為類型得到中的值,返回為類型,還有相應(yīng)的和函數(shù)。是最基礎(chǔ)的文件讀取類,支持對(duì)變量的解析。 Python 解析配置模塊之ConfigParser詳解 1.基本的讀取配置文件 -read(filename) 直接讀取ini文件內(nèi)容 -sections() 得到所有...
閱讀 1268·2023-04-26 01:38
閱讀 1469·2021-11-15 11:39
閱讀 3259·2021-09-22 15:43
閱讀 2653·2019-08-30 15:55
閱讀 2057·2019-08-30 14:17
閱讀 2859·2019-08-29 14:16
閱讀 3071·2019-08-26 18:36
閱讀 2616·2019-08-26 12:19