跳轉到內容

Python 初學者教程/檔案 I/O

來自華夏公益教科書,開放的書籍,開放的世界

在上節課中,我們學習瞭如何將外部程式碼載入到我們的程式中。無需任何介紹(就像我通常的做法),讓我們深入研究使用普通文字檔案的檔案輸入和輸出,以及隨後儲存和恢復類的例項。(哇,我們的術語能力已經大大提高了!)

開啟檔案

[編輯 | 編輯原始碼]

要開啟一個文字檔案,可以使用 open() 函式。看起來很合理。您需要向 open() 傳遞某些引數,告訴它以何種方式開啟檔案 - 'r' 表示只讀,'w' 表示只寫(如果存在舊檔案,它將被覆蓋),'a' 表示追加(在檔案末尾新增內容)和 'r+' 表示讀寫。但少說點,讓我們開啟一個檔案進行讀取(您可以在 Python IDLE 模式下執行此操作)。開啟一個普通的文字檔案。然後,我們將打印出我們在檔案中讀取的內容

程式碼示例 1 - 開啟檔案
openfile = open('pathtofile', 'r')
openfile.read()

這很有趣。你會注意到很多 '\n' 符號。這些代表換行符(你在哪裡按下回車鍵以開始新的一行)。文字完全沒有格式化,但如果要將 openfile.read() 的輸出傳遞給 print(透過鍵入 print openfile.read()),它將被很好地格式化。

尋找你所需要的東西

[編輯 | 編輯原始碼]

你嘗試過鍵入 print openfile.read() 嗎?它失敗了嗎?它很可能失敗了,原因是“游標”改變了位置。游標?什麼游標?好吧,一個你真的看不見的游標,但它仍然是一個游標。這個看不見的游標告訴 read 函式(以及許多其他 I/O 函式)從哪裡開始。要設定游標的位置,可以使用 seek() 函式。它以 seek(offset, whence) 的形式使用。

whence 是可選的,它決定從哪裡開始查詢。如果 whence 為 0,則位元組/字母從開頭開始計數。如果它為 1,則位元組從當前游標位置開始計數。如果它為 2,則位元組從檔案末尾開始計數。如果沒有在那裡輸入任何內容,則假定為 0。

offset 描述游標移動到 whence 的距離。例如

openfile.seek(45,0) 會將游標移動到檔案開頭後的 45 個位元組/字母。openfile.seek(10,1) 會將游標移動到當前游標位置後的 10 個位元組/字母。openfile.seek(-77,2) 會將游標移動到檔案末尾之前的 77 個位元組/字母(注意 77 之前的 -)。現在試試吧。使用 openfile.seek() 轉到檔案中的任何位置,然後嘗試鍵入 print openfile.read()。它將從您查詢的位置開始列印。但請意識到 openfile.read() 會將游標移動到檔案末尾 - 您需要再次查詢。

其他 I/O 函式

[編輯 | 編輯原始碼]

還有許多其他函式可以幫助您處理檔案。它們有很多用途,可以使您更強大,讓您所做的事情變得更容易。讓我們看看 tell()、readline()、readlines()、write() 和 close()。

tell() 返回游標在檔案中的位置。它沒有引數,只需鍵入它即可(就像下面的示例將顯示的那樣)。這對於知道您正在引用什麼、它在哪裡以及對游標的簡單控制非常有用。要使用它,鍵入 fileobjectname.tell() - 其中 fileobjectname 是您開啟檔案時建立的檔案物件名稱(在 openfile = open('pathtofile', 'r') 中,檔案物件名稱是 openfile)。

readline() 從游標所在位置讀取到行尾。請記住,行尾不是螢幕的邊緣 - 當您按下回車鍵以建立新行時,該行結束。這對讀取事件日誌或逐步處理某些內容非常有用。您不需要向 readline() 傳遞任何引數,儘管您可以選擇性地告訴它要讀取的最大位元組/字母數,方法是在括號中放入一個數字。將其與 fileobjectname.readline() 一起使用。

readlines() 類似於 readline(),但是 readlines() 從游標開始讀取所有行,並返回一個列表,每個列表元素包含一行程式碼。將其與 fileobjectname.readlines() 一起使用。例如,如果您有以下文字檔案

程式碼示例 2 - 示例文字檔案
Line 1

Line 3
Line 4

Line 6

從 readlines() 返回的列表將是

表 1 - readlines 返回的列表
索引
0 '第 1 行'
1 ''
2 '第 3 行'
3 '第 4 行'
4 ''
5 '第 6 行'

write() 函式將寫入檔案。你怎麼猜到的?它從游標所在的位置開始寫入,並覆蓋前面的文字 - 就像在 MS Word 中,您按下“插入”鍵,它就會覆蓋舊文字。要使用這個最有用的函式,在括號中放入一個字串以進行寫入,例如 fileobjectname.write('這是一個字串')。

close,您可能會想到,會關閉檔案,這樣您就不能再讀取或寫入它,直到再次開啟它。很簡單。要使用它,您需要寫入 fileobjectname.close()。簡單!

在 Python IDLE 模式下,開啟一個測試檔案(或建立一個新的...),並使用這些函式進行練習。您可以進行一些簡單的(非常不方便的)文字編輯。

在 Python 中,pickle 是儲存到檔案的物件。在這種情況下,物件可以是變數、類的例項、列表、字典或元組。其他事物也可以被 pickle,但有限制。該物件可以稍後恢復或取消 pickle。換句話說,您正在“儲存”您的物件。

那麼我們如何 pickle 呢?使用 dump() 函式,該函式位於 pickle 模組中 - 因此在程式開始時,您需要寫入 import pickle。很簡單吧?然後開啟一個空檔案,並使用 pickle.dump() 將物件放入該檔案中。讓我們試試這個

程式碼示例 3 - pickletest.py
### pickletest.py
### PICKLE AN OBJECT

# import the pickle module
import pickle

# lets create something to be pickled
# How about a list?
picklelist = ['one',2,'three','four',5,'can you count?']

# now create a file
# replace filename with the file you want to create
file = open('filename', 'wb')

# now let's pickle picklelist
pickle.dump(picklelist,file)

# close the file, and your pickling is complete
file.close()

首先,我們開啟 'filename' 以寫入二進位制資料 (wb) - open('filename', 'wb')

然後,我們將我們的列表轉儲到二進位制檔案。

執行此操作的程式碼如下所示:pickle.dump(object_to_pickle, file_object),其中

  • object_to_pickle 是您要 pickle 的物件(即將其儲存到檔案)
  • file_object 是您要寫入的檔案物件(在本例中,檔案物件是 'file')

在關閉檔案後,在記事本中開啟它,看看您看到了什麼。除了其他一些亂七八糟的東西,您會看到我們建立的列表的部分內容。

現在重新開啟或取消 pickle 檔案。要使用此功能,我們可以使用 pickle.load()

程式碼示例 4 - unpickletest.py
### unpickletest.py
### unpickle file

# import the pickle module
import pickle

# now open a file for reading
# replace filename with the path to the file you created in pickletest.py
unpicklefile = open('filename', 'rb')

# now load the list that we pickled into a new object
unpickledlist = pickle.load(unpicklefile)

# close the file, just for safety
unpicklefile.close()

# Try out using the list
for item in unpickledlist:
  print item

很不錯,對吧?

當然,上面的限制是,我們只能在一個檔案中放置一個物件。我們可以透過將許多可 pickle 的物件放入列表或字典中,然後 pickle 該列表或字典來解決這個問題。這是最快捷、最簡單的方法,但如果您對 pickle 有深入的瞭解,您可以做一些非常高階的事情。

或者,我們可以使用多個“pickle.dump(list, file)”函式:[1]

# pickle multiple lists
pickle.dump(list_1, file)
pickle.dump(list_2, file) 
...

以及多個“pickle.load(file)”函式

# unpickle multiple lists
list_read_1 = pickle.load(file)
list_read_2 = pickle.load(file) 
...

我們不會在這裡介紹複雜的例子。

參考資料

[編輯 | 編輯原始碼]
華夏公益教科書