跟我讀python3文檔:027_讀寫(xiě)文件(7.2. Reading and Writing Files)

貫穿始終的理念:別廢話,就是干!


往期回顧

  • 匿名函數(shù)lambda
  • 列表推導(dǎo)式
  • 數(shù)據(jù)結(jié)構(gòu)
  • 模塊

文檔解讀

python3文檔第七小節(jié)鏈接地址:7.2. Reading and Writing Files

本章主要講解7.2. Reading and Writing Files(讀寫(xiě)文件)這個(gè)小節(jié)


作者:咖喱py

文件讀寫(xiě)這部分相對(duì)好理解一些,就是:

  • 打開(kāi)文件 ?? 讀文件 ?? 關(guān)閉文件
  • 打開(kāi)文件 ?? 寫(xiě)文件 ?? 關(guān)閉文件

我們把這三部分分開(kāi)講:


第一部分:打開(kāi)文件

這一部分會(huì)略帶一點(diǎn)讀寫(xiě)文件的內(nèi)容。

讀文件就是用讀模式打開(kāi)文件,用讀方法讀取文件;
寫(xiě)文件就是用寫(xiě)模式打開(kāi)文件,用寫(xiě)方法寫(xiě)入文件。
關(guān)鍵詞就是:模式、方法

注意:讀和寫(xiě),是分開(kāi)的兩件事情!

接下來(lái)我們來(lái)看這兩件事情的異同之處。

>>> f = open('workfile', 'w')
  • open( )函數(shù)打開(kāi)文件,
  • 函數(shù)的第一個(gè)字符串參數(shù)代表文件,
  • 函數(shù)的第二個(gè)字符串參數(shù)代表模式,例如寫(xiě),常見(jiàn)的有如下模式字母:
字母 模式意義
'r' 讀取文件
'w' 寫(xiě)入文件,如果文件存在,則替換文件
'a' 續(xù)寫(xiě)文件
'b' 二進(jìn)制模式,常與其他字母組合使用

其他模式字母請(qǐng)參考文檔:模式字母

有些模式可以相互組合,比如:

  • 在模式后面加上b模式,可以進(jìn)行二進(jìn)制數(shù)據(jù)處理
  • 加上+(加號(hào)),代表我們可以對(duì)文件進(jìn)行讀寫(xiě)

可能+(加號(hào))那里你有點(diǎn)不理解他的意思。因?yàn)槟氵€沒(méi)有明白,“讀和寫(xiě)是兩件事”是什么意思。

我們繼續(xù)往下看例子,你很快就能明白。

寫(xiě)入文件:

  • 在寫(xiě)模式下,用寫(xiě)方法,即write( )方法
>>> a = open('test.py', 'w')                  #用寫(xiě)模式打開(kāi)文件,把文件對(duì)象賦值給a。
>>> a.write('This is the entire file.\n')     #用write()方法寫(xiě)入文件
25                                            #打印出寫(xiě)入的字符數(shù)量

讀取文件:

  • 在讀模式下,用讀方法,即read( )方法
>>> b = open('test.py', 'r')                  #用讀模式打開(kāi)文件,把文件對(duì)象賦值給b。
>>> b.read()                                  #用read()方法讀文件
'This is the entire file.\n'                  #文件內(nèi)容被打印出來(lái)

下面來(lái)體驗(yàn)一下什么叫做:讀和寫(xiě)是兩件事

在讀模式下,用write( )方法

>>> c = open('test.py', 'r')                   #用讀模式打開(kāi)文件,把文件對(duì)象賦值給c。
>>> c.write('galipy')                          #嘗試在讀模式中,寫(xiě)入內(nèi)容。
Traceback (most recent call last):             #程序出錯(cuò)
  File "<stdin>", line 1, in <module>
io.UnsupportedOperation: not writable

注意報(bào)錯(cuò)的最后一句話,寫(xiě)明了不支持寫(xiě)入操作。

也就是說(shuō),我們?cè)谧x模式,就只能讀取文件,不能寫(xiě)入文件。
在寫(xiě)模式,就只能寫(xiě)入文件,不能讀取文件。

現(xiàn)在明白“讀和寫(xiě)是兩件事”是什么意思了吧。
相當(dāng)于,如果你以讀模式打開(kāi)文件,那就只能讀取文件;如果還想要寫(xiě)入文件,就只能用寫(xiě)模式再打開(kāi)一遍文件。

那么有沒(méi)有什么辦法可以簡(jiǎn)化一下這個(gè)步驟呢?
答案就是:添加+(加號(hào))模式。

>>> c = open('test.py', 'r+')                   #用讀模式與加號(hào)模式打開(kāi)文件,把文件對(duì)象賦值給c。
>>> c.write('galipy')                           #嘗試在讀模式中,寫(xiě)入內(nèi)容。
6                                               #返回寫(xiě)入的字符數(shù)量

第二部分:讀寫(xiě)文件

這部分其實(shí)是講讀寫(xiě)文件的細(xì)節(jié)的

我們?cè)谶M(jìn)行讀或?qū)懖僮鲿r(shí),一定要時(shí)刻明白自己是從哪里讀,讀到哪了?從哪里寫(xiě),寫(xiě)在哪了?

你可能會(huì)天真的理解為從頭讀,從頭寫(xiě)。
但實(shí)際情況可能和你想的不太一樣。

長(zhǎng)者怎么說(shuō)的來(lái)著?
圖樣圖森破~

讀文件

#假設(shè)你有一個(gè)test.py文件,里面只寫(xiě)了一句話:'This is the entire file.'
#現(xiàn)在我們要讀取它

>>> b = open('test.py', 'r')                  #用讀模式打開(kāi)文件,把文件對(duì)象賦值給b。
>>> b.read()                                  #用read()方法讀文件
'This is the entire file.\n'                  #文件內(nèi)容被打印出來(lái)

#如果我們?cè)俅握{(diào)用read()方法會(huì)怎么樣?它會(huì)從哪開(kāi)始讀?還是從頭嗎?

>>> b.read()
''
#是不是沒(méi)有得到你想要的結(jié)果?

現(xiàn)在明白這個(gè)從哪讀到底是從哪讀了嗎?
當(dāng)你第一次啟動(dòng)read( )方法時(shí),它的確是從頭開(kāi)始讀的,但是當(dāng)你第二次調(diào)用read( )方法時(shí),它是接著上一次調(diào)用開(kāi)始讀的。
write( )方法也是一樣。如果你連續(xù)調(diào)用,那么他會(huì)連續(xù)接著寫(xiě)。

這樣有什么好處呢?這樣可以讓我們一次只讀取一部分,然后接著讀下一部分。

比如你有一個(gè)50G的文件,但你的電腦就2G內(nèi)存,你要怎么辦呢?如果你直接一次性打開(kāi),估計(jì)你的電腦就死機(jī)了。。。所以,我們需要分多次讀取。

>>> c.read(20)                      #一次讀取20個(gè)字符,然后多次調(diào)用

分次讀取還有一些其他的方法,比如:

c.readline()                         #一次讀取一行

或者

>>> for a_line in c:                 #用循環(huán)遍歷的方法一次讀取一行
...     print(a_line, end='')
...
This is the first line of the file.
Second line of the file

如果你想要讀取文件中所有的行,你也可以使用 list(f) 或 f.readlines()。

寫(xiě)文件

一開(kāi)始我們已經(jīng)接觸過(guò)寫(xiě)文件了,那么它有哪些需要注意的呢?

關(guān)鍵點(diǎn)在于write( )方法的參數(shù)!
這個(gè)參數(shù)必須是一個(gè)字符串!

也就是說(shuō),我們只能往文件里寫(xiě)入字符串類(lèi)型!
不能是整數(shù)類(lèi)型,不能是列表類(lèi)型,不能是其他任何類(lèi)型!
一定要記住write()方法的參數(shù)是字符串類(lèi)型這一點(diǎn),因?yàn)槲覀冊(cè)谥v解json時(shí),還會(huì)用到這點(diǎn)。

>>> a = open('test.py', 'w')                  #用寫(xiě)模式打開(kāi)文件,把文件對(duì)象賦值給a。
>>> a.write('This is the entire file.\n')     #用write()方法寫(xiě)入文件
25                                            #打印出寫(xiě)入的字符數(shù)量

要想寫(xiě)入其他類(lèi)型,我們也需要先把它們轉(zhuǎn)化為字符串類(lèi)型在寫(xiě)入

>>> value = ('the answer', 42)
>>> s = str(value)                             #把元組類(lèi)型轉(zhuǎn)化為字符串類(lèi)型了
>>> f.write(s)
18

讀寫(xiě)文件的主要細(xì)節(jié)就這些,不過(guò)還有一些拓展方法值得學(xué)習(xí):

  • tell()方法
    查看讀取到的位置
  • seek(offset, from_what)方法
    設(shè)置讀取位置

具體使用方法,請(qǐng)自行學(xué)習(xí)~


第三部分:關(guān)閉文件

為了保證文件內(nèi)容的正確性,同時(shí),為了節(jié)約內(nèi)存的使用,我們每次對(duì)文件進(jìn)行完操作之后都要關(guān)閉文件。

>>> a = open('test.py', 'w')                  #用寫(xiě)模式打開(kāi)文件,把文件對(duì)象賦值給a。
>>> a.write('本文作者是咖喱py.\n')              #用write()方法寫(xiě)入文件
11     
>>> a.close()                                 #用close()方法關(guān)閉文件

但是,一般情況下,我們的文件操作都是通過(guò)腳本文件執(zhí)行的。一旦程序運(yùn)行出錯(cuò),我們的close()操作可能就無(wú)法執(zhí)行。
為了保證close()正確執(zhí)行,于是我們就要用到try和finally兩個(gè)關(guān)鍵字。

注意!從現(xiàn)在開(kāi)始,我們要寫(xiě)腳本文件了,不再只是在交互模式里過(guò)家家了。

新建腳本firstFile.py
輸入如下內(nèi)容:

myfile = open('test.py','r')
try:
  for line in myfile:              #注意縮進(jìn)關(guān)系
    print(line, end='')
finally:
  my file.close()

文件會(huì)執(zhí)行try語(yǔ)句塊中的內(nèi)容,不論此語(yǔ)句塊中的內(nèi)容能不能成功運(yùn)行,程序最后都會(huì)去執(zhí)行finally語(yǔ)句塊中的內(nèi)容。
這樣就可以保證close()這個(gè)關(guān)閉操作100%運(yùn)行了。

但是,就像我最開(kāi)始那期的文章里介紹的,程序猿都是懶惰的,每次都輸入那么多很麻煩。

下面給出精簡(jiǎn)辦法,用with、as關(guān)鍵字:

with open('test.py','r') as myfile:
  for line in myfile:
    print(line, end='')

這三行代碼和上面的六行代碼做的是相同的事情。只不過(guò)有些操作被隱藏了起來(lái)。
參考著上面的try、finally語(yǔ)句塊,試試自己理解with、as語(yǔ)句塊發(fā)生了什么~

by_ 咖喱py


今天就講到這里吧~
記住write( )方法的參數(shù)特點(diǎn)喲~下期講解json將會(huì)用到~


最近發(fā)現(xiàn)文章被盜的很兇,而且還不署名。。。
你們的良心不會(huì)痛嘛~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容