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