Python十一課--檔案和流
一.開啟檔案
1.開啟檔案可以使用open函式,返回一個file object,具體用法如下
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
這裡的file是一個用文字字串表示的檔名,如果檔案不在當前目錄下則需要給出其完整路徑
buffering控制檔案的緩衝,0表示無緩衝,1表示有緩衝,-1表示使用預設緩衝區大小
mode預設值為r,表示對檔案只做讀操作,mode 為w表示寫操作(不可讀;不存在則建立;存在則會清空原有檔案的內容)
mode 為x表示建立一個新檔案並執行寫操作(不可讀;檔案存在會丟擲異常)
其餘引數的意義請參見幫助
2.如果需要開啟檔案c:\python\hello.txt,則可以:
>>> f = open(r'c:\python\hello.txt')
如果檔案不存在,則會得到如下提示:
Traceback (most recent call last):
File "<pyshell#93>", line 1, in <module>
f = open(r'c:\python\hello.txt')
FileNotFoundError: [Errno 2] No such file or directory: 'c:\\python\\hello.txt'
3.Python對開啟的是文字檔案還是二進位制檔案(例如聲音剪輯或者影象)進行區分,如果是二進位制檔案,則可以將引數b新增到其檔案開啟模式中使用
例如,使用mode=’rb’表示讀取一個二進位制檔案
引數+也可以用到其他任何模式中,表明讀和寫都是允許的,例如,r+ 模式(讀,追加模式)
>>> f = open('c:\python\hello.txt','r+',encoding='utf-8') >>> data = f.read() # 讀出檔案中的內容 >>> print(data) The aircraft has yet to actually take off, but the company behind Stratolaunch says it's expecting to perform a launch demonstration by "as early as 2019." >>> f.write("test...\n") 8 >>> print(f.read()) # 為什麼這裡的輸出是空的?見下 >>> f.tell() # 獲取檔案游標的現有位置 170 >>> f.seek(0) # 將檔案游標挪至檔案開頭 0 >>> print(f.read()) The aircraft has yet to actually take off, but the company behind Stratolaunch says it's expecting to perform a launch demonstration by "as early as 2019."test...
二.檔案的基本方法
1.讀和寫
(1.檔案(或流)最重要的能力是提供或者接收資料
(2.Python只能將字串寫入到文字檔案,要將數值資料儲存到文字本件中,必須先用內建函式str()將其轉換為字串格式
(3.如果有一個名為f的檔案物件,那麼可以用f.write方法和f.read方法(以字串形式)寫入和讀取資料
>>> f = open(r'c:\python\hello3.py', 'w’) >>> f.write('Hello, ') 7 # 返回寫入的位元組數 >>> f.write(‘world!’) # 呼叫write方法時引數被追加到檔案尾 6 >>> f.close() # 完成操作後需要呼叫close方法 執行完上面語句後,你會發現原來檔案中的內容被清空;如果確實是需要執行新增操作,則應將模式mode設為’a’ 讀取的時候告訴流需要讀取多少個字元即可 >>> f = open(r'c:\python\hello3.py', 'r') >>> f.read(5) # 讀取5個字元 'Hello' >>> f.read() # 讀取剩餘內容 ', world!' >>> f.close() 如果僅對檔案內容進行讀取,則無需指定開啟模式,因為預設值為r
2.管道輸出
(1.:在Unix的shell中典型的管道(pipeline)輸出命令形式為
cat somefile.txt | python somescript.py
cat somefile.txt把somefile.txt的內容寫到標準輸出(sys.stdout)
python somecript.py 執行指令碼,從標準輸入中讀取資料並將結果寫到標準輸出中
(2. 管道符號(|)的作用是將一個命令的標準輸出和下一個命令的標準輸入連在一起,這樣形如
cat somefile.txt | python somescript.py
的命令會告訴somecript.py從sys.stdin中讀取資料(cat somefile.txt寫入的),並將結果寫入sys.stdout
(3.在Windows系統中安裝cygwin(http://cygwin.com,a large collection of GNU and Open Source tools which provide functionality similar to a Linux distribution on Windows),並執行上面的命令
(4.
假設有一個指令碼檔案somescript.py,內容如下: # somescript.py import sys text = sys.stdin.read() words = text.split() wordcount = len(words) print('Word count:', wordcount) 另外還有一個文字檔案somefile.txt: Your mother was a hamster and your father smelled of elderberries.
以下是在cygwin環境中執行
cat somefile.txt | python somescript.py
命令的結果
注意:不使用管道輸出
# somescript.py f = open('c:\python\somefile.txt', 'r') data = f.read() words = data.split() wordcount = len(words) print('Word count:', wordcount)
3.隨機訪問
(1.除了按照從頭到尾的順序讀取資料外(將檔案作為流來處理),在檔案中隨意移動讀取位置也是可以的
(2.使用檔案物件的seek和tell方法來直接訪問感興趣的部分,這種做法稱為隨機訪問
seek(offset[, whence])
offset是位元組(字元)數表示的偏移量
whence預設值為0,表示偏移量從檔案頭開始計算(文字檔案與二進位制檔案均適用);
如果是1表示相對當前位置的偏移;如果是2則表示相對檔案尾的偏移(僅適用於二進位制檔案)
考慮下面這個例子 >>> f = open(r'c:\python\hello.txt', 'w') >>> f.write('01234567890123456789') >>> f.seek(5) # 把當前讀寫位置移動到第5個位元組處 >>> f.write(‘Hello, world!’) # 在當前位置寫入字串 >>> f.close() >>> f = open(r'c:\python\hello.txt') >>> f.read() '01234Hello, world!89‘ * 注意:可以用help(io.IOBase.seek)檢視關於seek的幫助資訊 tell方法返回檔案當前的讀寫位置 >>> f = open(r'c:\python\hello.txt') >>> f.read(3) '012' >>> f.read(4) '34He' >>> f.tell() 7
4.對行進行讀寫
(1.可以使用file.readline()讀取單獨的一行(從當前位置開始直到換行符出現)
(2.也可以使用帶非負整數的引數作為可以讀取的位元組(或字元)的最大值,例如file.readline(5)
(3.使用file.readlines()方法則讀取一個檔案中所有行並將其作為列表返回,類似於fileinput.input()(返回FileInput類的物件)
(4.writelines方法和readlines方法正好相反:傳給它一個字串的列表(實際上任何序列和可迭代物件都行),它會將所有字串寫入檔案。另外,沒有writeline方法,可使用write方法寫入一行
>>> f = open(r'c:/python/fileinputoutput.txt', 'x') >>> lst = ['This is the first line.', 'This is the second line.', 'And this is the third line.'] >>> f.writelines(lst) >>> f.close() 如果指定檔案不存在則建立新檔案,顯示結果如下: This is the first line.This is the second line.And this is the third line. 由此看來,程式不會自己增加新行,需要自己在每行後新增換行符,用於文字檔案中寫入時使用的行分隔符是’\n’
5.關閉檔案
(1.應該牢記在使用完檔案後呼叫close()進行關閉。寫入過的檔案總是應該關閉,是因為Python可能會快取寫入的資料;如果程式因為某些原因崩潰了,那麼資料就不會寫入檔案中
(2.為了確保關閉檔案,可以使用try/finally語句,並且在finally中呼叫close方法
f = open(r'c:/python/fileinputoutput.txt‘) try: # write data to your file finally: f.close()
(3.事實上有專門為這種情況設計的語句,即使用with語句管理上下文
>>> with (open(r'c:/python/fileinputout.txt')) as somefile: do_something(somefile)
這裡with語句開啟檔案並將其賦值到變數somefile上,之後可以執行對檔案的其它操作,操作結束後文件會自動關閉,即使是由於異常引起的結束也是如此
在Python 2.7 後,with支援同時對多個檔案的上下文進行管理,即:
with open('log1') as obj1, open('log2') as obj2:
pass 例如, >>> with open(r'c:/python/hello.txt', encoding = 'utf-8') as f1, open(r'c:/python/hello4.txt', encoding = 'utf-8') as f4: print(f1.read()) print(f4.read())
6.基本的檔案方法
(1.假設現在有一個文字檔案fileinputoutput.txt,其內容為
Welcome to this file
There is nothing here except
These three lines
然後我們使用檔案的各種讀寫方法
>>> f = open(r'c:/python/fileinputoutput.txt') >>> f.read(7) # 從檔案當前位置讀入7個位元組 'Welcome' >>> f.read(4) ' to ' >>> f.close() >>> f = open(r'c:/python/fileinputoutput.txt') >>> print(f.read()) # 讀取檔案所有內容 Welcome to this file There is nothing here except These three lines 還可以使用readline()來讀取檔案所有內容 >>> f = open(r'c:/python/fileinputoutput.txt') >>> for i in range(3): print(f.readline(), end=' ') Welcome to this file There is nothing here except These three lines 試試readlines方法,將會讀取換行符 >>> import pprint >>> pprint.pprint(open(r'c:\python\fileinputoutput.txt').readlines()) ['Welcome to this file\n', 'There is nothing here except\n', 'These three lines']
7.寫檔案
使用write方法寫入一行或多行檔案內容 >>> f = open(r'c:\python\fileinputoutput.txt', 'w') >>> f.write('This\n is\n another\nstring.') 25 >>> f.close() 使用writelines方法寫入多行檔案內容 >>> f = open(r'c:\python\fileinputoutput.txt', 'w’) >>> lst = ['Welcome to this file\n', 'There is nothing here except\n', 'These three lines'] >>> f.writelines(lst) >>> f.close()
三.對文章內容進行迭代