[Python] 詳細解答 open 函數(shù)中 r 和 rb 的區(qū)別

引用

普通部分

rb主要是為了讀取二進制文件而創(chuàng)立的字段,因為二進制字段中很有可能有1A(\x)這個編碼,但是這個在普通文件中表示的EOF,即文檔結(jié)束符,所以如果使用r讀取二進制文件就會造成將1A當成文件結(jié)束符,導(dǎo)致這個字符后面的部分沒有讀取上,出現(xiàn)文檔讀取不全的現(xiàn)象。
如果我們讀取人工書寫的數(shù)據(jù)那么就使用r,如果我們讀取非人工書寫的數(shù)據(jù)那么我們就是使用rb,圖片就是一種非常典型的非人工書寫數(shù)據(jù)。

with open('photo.jpg', 'rb') as f:
    jpgdata = f.read()

高階部分

  • 如果使用的mode是r,那么你就要非常清楚,這個數(shù)據(jù)是用什么編碼來書寫的,讀取的時候也要用對應(yīng)的編碼,否則就有可能由于解碼錯誤,導(dǎo)致亂碼。因為對于計算機來說,只有字符(byte),而沒有(str),而將byte翻譯成str的方式就是依據(jù)encoding的方式而定的,所以我們可以通過設(shè)置encoding字段來指定解碼格式,utf-8是現(xiàn)在的主流編碼方式,如果沒有指定encoding 的方式那么根據(jù)python版本的不同會有不同的解碼方式,Python3中是utf-8,而python2中是ascii。
>>> # Python2
>>> import sys
>>> sys.getdefaultencoding()
'ascii'

 >>> # Python3
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
  • open函數(shù)返回的是一個句柄,是將操作系統(tǒng)所持有的句柄交給open函數(shù),當然我們需要對文件操作結(jié)束以后調(diào)用close函數(shù),將關(guān)閉這個句柄,因為每個程序打開文件數(shù)量是有上限的,只有打開之后進行關(guān)閉,才不會觸及這個上限,但是有個問題就是如果在open函數(shù)和close函數(shù)之間程序運行發(fā)生了錯誤,那么就會導(dǎo)致句柄沒有關(guān)閉,這不是我們希望看到了,所以為了保證是否有錯誤發(fā)生都要關(guān)閉句柄,我們可以使用with語句,句柄只有在with語句內(nèi)部是可以使用的,如果在with語句外面(比如出錯時候的traceback)句柄是自動關(guān)閉的,所以就解決了這一個痛點。

小例子

b,u,r
因為在window系統(tǒng)里面 回車是用\r\n表示的,Linux系統(tǒng)離水面回車使用\n表示的,說明mode是rb的時候,寫的時候系統(tǒng)寫進文件的二進制編碼是什么就按什么方式呈現(xiàn)出來,字符串前面是b表示這個是一個byte類型的對象,只不過輸出臺將這個轉(zhuǎn)換成了人能讀懂的形式。

f=open('C:\\Users\\MapReducer\\Desktop\\text.txt','rb')
for line in f:
    print(line)
>>
#
b'name: James\r\n'
b'age: 20\r\n'
b'---\r\n'
b'name: Lily\r\n'
b'age: 19'

因為文件中每一行的末尾有一個回車,print函數(shù)也會自己在輸出一個回車,所以輸出兩個空格,說明了如果mode是r的話,人寫進去的是什么形式的讀出來就是什么形式的,不管在什么系統(tǒng)下回車的編碼方式是什么。

f=open('C:\\Users\\MapReducer\\Desktop\\text.txt','r')
for line in f:
    print(line)
>>
name: James
age: 20

---

name: Lily

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

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