零基础学习 Python 之文件
讀取文件
假設(shè)你已經(jīng)在某個(gè)文件夾下創(chuàng)建了 “test.txt” 文件,且里面有一些內(nèi)容,那你在當(dāng)前位置輸入 Python3,進(jìn)入到交互模式,然后執(zhí)行下面的操作:
>>> f = open('test.txt') >>> for line in f: ... print(line) ... My name is RockyI love Python 復(fù)制代碼這里提醒大家注意一下,如果是在該文件所在的位置啟動(dòng)的 Python 交互模式,那么按照上面的方法 open(‘test.txt’) 打開文件,這意味著 test.txt 是在當(dāng)前文件夾下的,如果要打開其它文件夾下的文件,要使用相對(duì)路徑或者絕對(duì)路徑來(lái)表示,從而讓 Python 能找到那個(gè)文件。
看上面的例子,open() 一個(gè)文件,即生成了一個(gè)對(duì)象,把這個(gè)對(duì)象賦值給變量 f,從而讓變量 f 和文件對(duì)象之間建立了引用關(guān)系,接下來(lái)用 for 循環(huán)讀取文件中的內(nèi)容,把讀到的文件中的每行賦值給變量 line (這里的每行可以看作是對(duì)象),從打印的結(jié)果看,每一行與你讀取的文件的每一行是相同的。
如果你做完了上述操作,那么請(qǐng)看下面的操作:
>>> for line1 in f: ... print(line1) ... >>> 復(fù)制代碼你會(huì)奇怪的發(fā)現(xiàn),竟然什么也沒(méi)有,是不是出錯(cuò)了?其實(shí)并沒(méi)有,因?yàn)橹耙呀?jīng)讀取過(guò)一次文件的內(nèi)容了,并且到了文件的末尾,再重復(fù)操作,就要從文章的末尾開始讀了,當(dāng)然就沒(méi)有什么東西了,在 Python 中并不會(huì)認(rèn)為這是錯(cuò)誤。如果你想再次讀取的話,請(qǐng)重新 open() 一下文件。
創(chuàng)建文件
讀文件只是針對(duì)文件的操作之一,還有創(chuàng)建文件。
在上面讀文件的時(shí)候,我們打開的是一個(gè)已經(jīng)存在的文件,那么如何創(chuàng)建一個(gè)新文件呢?請(qǐng)看下面的操作:
>>> new_file = open('new.txt','w') >>> new_file.write('this is a new file') 18 >>> new_file.close() 復(fù)制代碼new_file = open(‘new.txt’,’w’) 意味著在當(dāng)前的目錄下創(chuàng)建了一個(gè)名為 new_file 的文件,該文件為 “w” 打開模式。
new_file.write('this is a new file’) 則是向已建立的新文件中寫入 “this is a new file”,并且返回的是寫入字符串的長(zhǎng)度。
new_file.close() 則是關(guān)閉當(dāng)前文件,然后將寫入的話保存到文件中。
由上面的例子我們可以看出,創(chuàng)建文件我們同樣用的是 open() ,但是多了個(gè) “w” ,這是告訴 Python 用什么模式打開文件。在 Python 中,可以用很多不同的模式打開文件,請(qǐng)看下圖(截圖來(lái)自菜鳥教程):
從上圖中可以看出,不同的模式下打開文件可以進(jìn)行不同的讀寫操作,如果什么都不寫的話,默認(rèn)為以只讀(r)的方式打開文件。使用 with 自動(dòng)關(guān)閉文件
在前面的操作中我們可以看到,在對(duì)文件進(jìn)行寫操作之后,要執(zhí)行關(guān)閉文件的操作,執(zhí)行關(guān)閉文件的操作是為了將寫入的內(nèi)容保存到文件中,如果不進(jìn)行 close() 操作的話,那么新寫入的內(nèi)容將不會(huì)被保存。
Python 早就知道會(huì)有很多馬大哈們會(huì)忘記 close()的操作,所以它創(chuàng)建了一種簡(jiǎn)單的方法,這就是 with,它會(huì)實(shí)現(xiàn)自動(dòng)關(guān)閉文件,看!Python 是多么的人性化!請(qǐng)看下面的操作:
>>> new_file.close() >>> with open('new.txt','a') as f: ... f.write(‘\nwith is good good good.') ... 23 復(fù)制代碼在這里 with 其實(shí)是要發(fā)起一個(gè)語(yǔ)句的,這里兼具了后面我會(huì)講的 try/finally,即可以在遇到異常的時(shí)候發(fā)出提醒,此處暫時(shí)先不講,等以后我再細(xì)說(shuō),我們先學(xué)會(huì)用 with。
>>> with open('new.txt') as f: ... print(f.read()) ... this is a new file with is good good good. 復(fù)制代碼看吧,在 with 中我們可以放輕松的扔掉 close 了,上面例子中用到的 read() 方法,在明天的文章中我會(huì)講到。
文件的屬性
很多時(shí)候,我們需要獲取一個(gè)文件的有關(guān)屬性,比如文件的創(chuàng)建日期,修改日期等等,在 Python 中有一個(gè)專門針對(duì)時(shí)間設(shè)計(jì)的模塊 -- time。請(qǐng)看下面的操作:
>>> import time >>> time.localtime() time.struct_time(tm_year=2018, tm_mon=7, tm_mday=25, tm_hour=21, tm_min=49, tm_sec=32, tm_wday=2, tm_yday=206, tm_isdst=0) 復(fù)制代碼其實(shí)還有一種辦法可以查看文件的這些屬性,就是 os 模塊里的 stat,在這里我就是提一嘴,之后講到 os 模塊的時(shí)候再仔細(xì)說(shuō)。
讀取文件的內(nèi)容
因?yàn)槲募膶?duì)象是可迭代的,所以能夠用open() 打開文件,所以用 for 循環(huán)可以將文件的內(nèi)容讀出來(lái)。我在前面的文章說(shuō)過(guò),可以用 dir() 查看文件對(duì)象的屬性和方法,當(dāng)你看了以后你會(huì)發(fā)現(xiàn)有 3 個(gè)方法 read / readline / readlines,單單從名稱上看,它們應(yīng)該和讀有關(guān)系,事實(shí)上確實(shí)是這樣的,但是它們 3 個(gè)又有些微的差別。
1.read()
文件對(duì)象的 read() 方法,其實(shí)完整的寫出來(lái)其實(shí)是 read( size ),只不過(guò)里面的參數(shù)可以省略,如果不省略,則讀取文件中的 size 個(gè)字符并返回一個(gè)字符串;如果省略的話,則讀取文件對(duì)象的字符知道 EOF,EOF == End - of - file。
>>> f = open('new.txt') >>> f.read(10) 'this is a ' >>> f.read() 'new filewith is good good good.’ 復(fù)制代碼如果你是按照上述的例子依次進(jìn)行操作的,就會(huì)在 f.read() 后出現(xiàn)上述的結(jié)果,這主要是因?yàn)樵谇懊嬉呀?jīng) read(12) 了,指針已經(jīng)移動(dòng)到了第 12 個(gè)字符后面。
2.readline() & readlines()
readline() 就是它表面的意思,逐行讀取文件的內(nèi)容。
>>> f = open('new.txt') >>> f.readline() 'this is a new filewith is good good good.' >>> f.readline() '' 復(fù)制代碼每次執(zhí)行 readline() 的時(shí)候它只讀一行,直到最后一行,如果還執(zhí)行 readline() 的話,它不會(huì)報(bào)錯(cuò),返回的是空字符串。
同樣也是有 readline(size) 的,如果給 readline(size) 參數(shù),則讀取相應(yīng)行的 size 個(gè)字符,有興趣的可以自己試一下。
還有一個(gè)是 readlines(),它的作用是將文件中各行讀出來(lái),放到一個(gè)列表中返回。
>>> f = open('test.txt') >>> f.readlines() ['My name is Rocky\n', 'I love Python’] 復(fù)制代碼既然返回的是一個(gè)列表,那么就能用 for 循環(huán)讀取列表元素,再觀察一下可以發(fā)現(xiàn),列表中的每個(gè)元素都是文件的一行,并且是字符串。
>>> f = open('test.txt') >>> for line in f.readlines(): ... print(line) ... My name is RockyI love Python 復(fù)制代碼這個(gè)是不是讓你覺得和上面文件的 for 循環(huán)很類似?
>>> f = open('test.txt') >>> for line in f: ... print(line) ... My name is RockyI love Python 復(fù)制代碼乍一看兩種方式好像沒(méi)有什么區(qū)別,其實(shí)這兩種方式是不同的。在 for line in f 中,并沒(méi)有將文件中所以的行都讀入內(nèi)存,而 for line in f.readlines() 中先執(zhí)行了 f.readlines(),在內(nèi)存中有一個(gè)列表,列表中包含了所有文件的行,這就是兩種方式的區(qū)別。
大文件的讀取
上面的三個(gè)讀取文件內(nèi)容的方法 read 和 readlines 都是一次性將全部的內(nèi)容讀入內(nèi)存,如果文件不是很大的話,這種做法能夠保證讀取的速度,但是如果文件內(nèi)容很大,大到差不多內(nèi)存那么大或者更大的時(shí)候,就不能這么做了。但是 Python 早就替你考慮到了,Python 中有一個(gè) fileinput 模塊,可以使用它來(lái)操作。
>>> import fileinput >>> for line in fileinput.input('test.txt'): ... print(line,end = '') ... My name is Rocky I love Python 復(fù)制代碼因?yàn)槲覜](méi)有大的文件,只是為了演示一下這個(gè)模塊的用法,對(duì)于這個(gè)模塊更多的內(nèi)容,可以在交互模式下用 dir() 去查看。
seek
不知道你有沒(méi)有奇怪過(guò)在之前的演示中,每次都要做 f = open(‘***’) 類似的操作,否則就會(huì)出現(xiàn)下面的情況:
>>> f = open('test.txt') >>> for line in f: ... print(line) ... My name is RockyI love Python >>> for line in f: ... print(line) ... >>> 復(fù)制代碼是不是發(fā)現(xiàn),當(dāng)我們第二次循環(huán)文件的時(shí)候,既沒(méi)有報(bào)錯(cuò),也沒(méi)有顯示文件的內(nèi)容,類似的現(xiàn)象在前面的 readline 中也出現(xiàn)過(guò),這是因?yàn)樽x取文件的時(shí)候,有指針隨著運(yùn)動(dòng),當(dāng)讀取結(jié)束時(shí),指針就到了相應(yīng)的位置。
當(dāng)指針結(jié)束運(yùn)動(dòng)時(shí),可以使用 tell() 告訴我們當(dāng)前指針的位置。
>>> f = open('test.txt') >>> f.readline() 'My name is Rocky\n' >>> f.tell() 17 復(fù)制代碼現(xiàn)在我們來(lái)看 seek() 的能力,它能夠根據(jù)偏移量來(lái)移動(dòng)指針。
>>> f.seek(0) 0 復(fù)制代碼上面的意思是將指針移動(dòng)到文件的開始,如果用 f.readline() 讀取的話,現(xiàn)在輸出的應(yīng)該是文件的第一行:
>>> f.readline() 'My name is Rocky\n’ 復(fù)制代碼其實(shí)還可以操縱指針到任何一個(gè)位置,請(qǐng)看下面的操作:
>>> f.seek(10) 10 >>> f.tell() 10 復(fù)制代碼f.seek(10) 就是將位置定位到從開頭算起到第 10 個(gè)字符后面,這時(shí)候如果使用 readline 的話,讀取的是從當(dāng)前位置到行末的字母。
寫在之后
更多內(nèi)容,歡迎關(guān)注公眾號(hào)「Python空間」,期待和你的交流。
總結(jié)
以上是生活随笔為你收集整理的零基础学习 Python 之文件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 三星:车规级 GDDR7 专为超高带宽计
- 下一篇: 特斯拉先发优势正逐渐丧失,业界群起痛戳马