python open()函數的模式選擇


python open()函數打開文件的模式詳解

使用python處理文件時,避免不了要用到open()函數。我們今天主要討論mode參數的區分。

fd = open('文件名(路徑)’, mode=‘模式’)

先放上stockoverflow上一個哥么做的圖,很清楚的從總體上概括了mode的區分;

圖中展示了幾種主要的模式,r(只讀),r+(讀寫),w(只寫), w+(讀寫), a(追加),a+(追加讀)

 

從功能上分類:模式r只有讀的功能,模式w和a只有寫的功能,模式r+,w+和a+擁有讀和寫的功能。

讀的功能就是,文件讀入的對象可以使用read讀取文件內容,不用使用write方法向寫入內容;寫的功能是反過來的,

可以使用write方法向寫入內容,不用使用read讀取文件內容,而讀寫就是這兩個功能都有。

 

說到這里模式之間的區別還是不清楚。我們可以接着看下面這張圖來進一步認識模式間的區別:

------------------| r r+ w w+ a a+ read | + + + + write | + + + + + write after seek | + + + create | + + + + truncate | + + position at start |+ + + + position at end | + +

1,r和r+的區別

先試着執行下面代碼:

1 fd1 = open('newfile1.txt', mode='r')
2 fd2 = open('newfile2.txt', mode='r+')

如果你的工作目錄下沒有newfile.txt的話,運行這兩行代碼會出現FileNotFoundError報錯信息,告訴

你“本路徑下沒有名叫newfile.txt的這個文件”,可以先創建一個名為newfile.txt的文件再執行上面代碼就不會出問題了,

接着執行:

1 fd1.read()
2 fd2.read()

代碼正常執行,返回空字符串;返回空字符串是因為你的文件里什么原本就什么就沒有

接着執行:

1 fd1.write('this is test')
2 fd2.write('this is test')

第一行代碼報錯io.UnsupportedOperation: not writable,第二行代碼正常運行,這里就是r和r+的區別了

r只有讀的功能,r+既有讀的功能,也有寫的功能。

2,w和w+的區別

1 fd1 = open('newfile1.txt', mode='w')
2 fd2 = open('newfile2.txt', mode='w+')
3 fd1.write('this is test')
4 fd2.write('this is test')
5 fd1.read()
6 fd2.read()

與r和r+不同的是,無論當前目錄下有沒有名字為newfile.txt的文件,第一第二行都會正常運行,如果沒有的話會在當前目錄下創建一個名為newfile.txt的文件。

第三第四行也會正常運行,並將字符串寫入文件,

第五行會報錯:io.UnsupportedOperation: not readable,第六行會正常運行;這說明w和w+的區別是后者兼有讀寫功能,前這只有寫的功能。

第六行雖然運行成功了,但是返回的確是空字符串,問題是我們在讀取之前已經寫入了內容呀?這

是因為寫入結束之后我們的指針放在文件的末尾,這時候你讀取的就是末尾之后的東西,也就是空

字符串了。可以嘗試一下方法解決:

(1)先關閉文件再打開文件讀取

1 fd2.close()
2 fd2 = open('newfile2.txt', mode='r')
3 fd2.read()

這樣的話會正常顯示我們之前寫入的內容,這個方法未免太“折騰”了

(2)移動指針到文件開頭再讀取

1 fd2.seek(0)
2 fd2.read()

這樣也可以成功讀取剛寫入的內容,seek(0)中的0表示offset=0,偏移0個字符,還有一個參數whence默認為0代表從文件開始位置,另外還有1代表當前位置,2代表文件末尾。

3,a和a+的區別:

模式a和a+之間的區別與w和w+之間的區別相同,在此不做贅述

4,a和w的區別

模式a和w都是寫,區別就在於從哪里開始寫,為了說明問題,我們先新創建兩個文件new1.txt和new2.txt內容都為:

this is test1
this is test2
this is test3

然后執行下面代碼:

1 fd1 = open('new1.txt', mode='w')
2 fd1.write('try to update')
3 fd1.seek(0)
4 fd1.read()

輸出的結果為:

try to update

new1.txt文件中的原始內容被“沖洗”掉了!,我們再試試追加模式a

1 fd2 = open('new2.txt', mode='a')
2 fd2.write('try to update')
3 fd2.seek(0)
4 fd2.read()

返回的結果為:

this is test1
this is test2
this is test3
try to update

在文本的末尾添加了新寫入的內容。上面就是模式w和a的區別,w在打開文件的

時候將指針移動到文件開頭並截斷(truncate)了之后的所有內容,截斷即刪除掉了。

而模式a開打文件的時候,其指針的位置是在文件的末尾。所以寫入新內容的時候

這兩種模式就會不一樣。

值得一提的是,以模式a打開一個當前目錄下不存在的文件也同樣會新創建該文件。

5,r+和w+之間的比較

r+和w+之間是有必要拿出來比較一下的,因為他們的功能還是很像的,先說相同點

(1)都是可讀可寫的

(2)打開文件時指針都位於開始位置

再說不同點,創建兩個新文件new3.txt和new4.txt內容都為:

this is one
this is two
this is three

嘗試以下代碼:

1 fd3 = open('new3.txt', mode='r+')
2 fd3.write('1234')
3 fd3.seek(0)
4 fd3.read()

返回的結果是:

1234 is one
this is two
this is three

僅僅是替換了new3.txt原來位置的字符,其他未變!我們再試試w+

1 fd4 = open('new4.txt', mode='w+')
2 fd4.write('1234')
3 fd4.seek(0)
4 fd4.read()

返回的結果為:

1234

結果一目了然了。

 

關於with open:

使用Python內置的open()函數打開文件,如果文件不存在,open()函數就會拋出一個IOError的錯誤,並且給出錯誤碼和詳細的信息告訴你文件不存在:

>>> f=open('/Users/michael/notfound.txt', 'r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/notfound.txt'

如果文件打開成功,則可以根據文件對象對文本內容進行操作,如調用read()方法可以一次讀取文件的全部內容:

>>> f.read()
'Hello, world!'

最后一步是調用close()方法關閉文件,用來釋放文件對象占用操作系統的資源

>>> f.close()

由於文件讀寫時都有可能產生IOError,一旦出錯,后面的f.close()就不會調用。所以,為了保證無論是否出錯都能正確地關閉文件,我們可以使用try ... finally來實現:

try:
    f = open('/path/to/file', 'r')
    print(f.read())
finally:
    if f:
        f.close()

但是每次都這么寫實在太繁瑣,所以,Python引入了with語句來自動幫我們調用close()方法:

with open('/Users/michael/notfound.txt', 'r') as f:
    print(f.read())

這和前面的try ... finally是一樣的,但是代碼更佳簡潔,並且不必調用f.close()方法。

 

另,with open() as f的方式可以同時管理多個文件對象,如下:

with open('/Users/michael/notfound1.txt', 'r') as fr,open('/Users/michael/notfound2.txt', 'w') as fw,:
for line in fr.readlines():
fw.write(line)

 

讀取超大文件時,如幾十G文件,為了避免一次讀取全部內容,可以使用with open()獲取文件句柄進行逐行讀取,每次內存中只保存一行數據:

with open("test.txt") as f:
    for line in f:
        #do something with data

 

 

源鏈接:https://www.cnblogs.com/hanweiblog/p/9385644.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM