open函數使用一個文件名作為唯一的強制參數,然后返回一個文件對象。
一 r 模式與 rb 模式的區別
r 模式,需要指定編碼,windows下默認是gbk編碼。rb模式直接讀取二進制,與編碼沒有關系,加上就報錯。
with open('1.txt','rb') as f: data=f.read() print(data,type(data))
輸出:
b'\xe4\xbc\x98\xe9\x85\xb7\n' <class 'bytes'>
如果在 rb模式下,強行加上encoding,報錯。
with open('1.txt',encoding='utf-8',mode='rb') as f: data=f.read() print(data,type(data))
報錯信息:
ValueError: binary mode doesn't take an encoding argument
一般情況下要指定encoding,windows下默認是gbk,如果保存的時候是gbk,不加上encoding是可以的。
以下代碼是在windows下運行。
with open('1.txt','r') as f: data=f.read() print(data,type(data))
輸出:
優酷 <class 'str'>
因為文件1.txt,我是以gbk編碼格式保存的。
二 w 模式與 wb 模式
與 r 模式 和 rb 模式類似,b指的就是bytes類,所以采用 wb模式,寫入的必須是bytes格式。同樣不要指定encoding,否則會報錯!
with open('1.txt',encoding='utf-8',mode='wb') as f: f.write('中國'.encode(encoding='utf-8'))
報錯信息:
ValueError: binary mode doesn't take an encoding argument
更改如下:
with open('1.txt',mode='wb') as f: f.write('中國'.encode(encoding='utf-8'))
沒有報錯,正常寫入。b 模式下,一定要寫入bytes格式!!!!
總結: b 模式下,一定要注意,不要寫encoding模式,一定不要!!!!!
三 文件方法:
'+'參數可以用到其他任何模式中,指明讀和寫都是允許的。
b 模式一般是用於聲音剪輯或者圖像,原理比較復雜。
1 f.read() 可以傳整數格式的參數,在不同模式下,整數的含義並不一樣。
在 r 模式下,代表的是一個字符。因為我在1.txt中寫的是漢字,所以輸出結果是3.,代表3個字節。如果文件中是數字或者字母,返回的則是 1 。
with open('1.txt',encoding='utf-8',mode='r+') as f: f.read(1) print(f.tell())
輸出:3
在 rb 模式下,代表的是一個字節,所以不管是一個漢字還是數字還是字母,返回的都是 1 。
with open('1.txt',mode='rb+') as f: f.read(1) print(f.tell())
輸出:1
2 seek方法:
Change the stream position to the given byte offset。
指定指針位置,兩個參數,第一個參數表示移動的 字節數,特別強調,是字節數。 。 第二個參數。0代表從文件開始位置,1 代表從文件當前位置,2 代表從文件末尾,可以省略,默認是0
Move to new file position and return the file position. Argument offset is a byte count. Optional argument whence defaults to SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values are SEEK_CUR or 1 (move relative to current position, positive or negative), and SEEK_END or 2 (move relative to end of file, usually negative, although many platforms allow seeking beyond the end of a file). Note that not all file objects are seekable
seek方法的應用:
f=open('1.txt',mode='r+',encoding='utf-8') f.write('dsdfdfsd') # f.seek(0) a=f.read() f.close() print(a)
在注釋掉f.seek()后,輸出 空。
注意:
當文件是以 r 模式打開時,seek方法只支持第二個參數為 0,強行從當前位置,或者末尾位置會報錯。
只有文件以 b 模式打開,seek方法才允許 偏移位置從當前位置(參數為1)或者從末尾位置(參數為2)開始。
舉例:
f=open('1.txt',mode='r+',encoding='utf-8') f.seek(-6,2) print(f.tell()) f.truncate() f.close()
會報錯:
io.UnsupportedOperation: can't do nonzero end-relative seeks
換成 b 模式就可以了。
f=open('1.txt',mode='rb+') f.seek(-6,2) print(f.tell()) f.truncate() f.close()
正常運行
f=open('1.txt',mode='r+',encoding='utf-8') f.write('hello world') f.seek(0) a=f.read() f.close() print(a)
f.seek()沒被注釋的情況下,輸出‘hello world’。
輸出:
hello world
總結:
f.write()調用后,光標移到了white所寫的內容末尾。
f.read()是從光標開始的位置開始讀取。
要有這兩個概念,所以上述兩個例子,就說明了這個問題,也把seek方法的作用展示出來了。
3 truncate方法:用於截斷文件,如果指定了可選參數 size,則表示截斷文件為 size 個字符,指的是從文件開頭截取size字節大小的字符串,注意是字節大小,其余的都刪掉,這種情況下,不會考慮光標在什么位置。 如果沒有指定 size,則從當前光標位置起截斷,光標后面的字符串都被刪掉。
四 重中之重!
with open('1.txt',encoding='utf-8',mode='r+') as f: for line in f: #非常經常的會遇到,會使用到。 print(line)
l=[] from collections import Iterable with open('1.txt',encoding='utf-8',mode='r+') as f: #文件句柄 f 是可迭代對象,單論這一點和列表,字符串,字典,元組沒什么區別。所以可以 for line in f:line取到的是字符串格式。 print(f,type(f)) print(isinstance(f,Iterable)) print(isinstance(l,Iterable))
五 類文件
類文件對象是支持一些file類方法的對象,最重要的是支持read方法或者write方法。類文件對象,有時成為 流。
比如sys模塊中的 sys,stdin sys.stdout sys.stderr
六
1 關於 f 的說明
f=open('1.txt','w',encoding='utf-8') f.write('123') f.close() print(f) f.read()
輸出:
<_io.TextIOWrapper name='1.txt' mode='w' encoding='utf-8'> Traceback (most recent call last): File "D:/Program Files/JetBrains/s7/day29/client1.py", line 23, in <module> f.read() ValueError: I/O operation on closed file.
解釋器打開文件,解釋器內存中存執 f ,這個就是一個單純的變量名。
打開的文件是在計算機內存中,文件的打開與關閉涉及到硬件底層,這是由操作系統來干的,不可能有解釋器執行。打開的文件是在計算機內存中。f.close()是系統調用,告訴操作系統這個文件已經沒用的,可以關閉了。
但 f 這個變量名還是在python解釋器的內存中。不過,此時,再用 f 去調用 read 方法,就會報錯,因為在內存中的文件已經沒有了。
2 關於f=open(filename,encoding='utf-8')
為什么指定encoding,因為 f =open ,只是有python提出系統調用,但真正執行打開操作的是操作系統。所以encoding是給操作系統設定的。一句話,open,send,close,是系統調用,真正執行時操作系統,因為涉及到底層硬件。