天天看點

《Python程式設計快速上手——讓繁瑣工作自動化》第八章第8章 讀寫檔案

第8章 讀寫檔案

8.1 檔案與檔案路徑

雖然檔案夾名稱和檔案名在Windows和OS X上是不區分大小寫的,但在Linux上是區分大小寫的。

8.1.1 Windows上的倒斜杠以及OS X和Linux上的正斜杠

如果将單個檔案和路徑上的檔案夾名稱的字元串傳遞給它,os.path.join()就會傳回一個檔案路徑的字元串,包含正确的路徑分隔符。

>>> import os
>>> os.path.join('usr', 'bin', 'spam')
'usr\\bin\\spam'
           

如果需要建立檔案名稱的字元串,os.path.join()函數就很有用。例如,下面的例子将一個檔案名清單中的名稱,添加到檔案夾名稱的末尾。

>>> myFiles = ['accounts.txt', 'details.csv', 'invite.docx']
>>> for filename in myFiles:
        print(os.path.join('C:\\Users\\asweigart', filename))
C:\Users\asweigart\accounts.txt
C:\Users\asweigart\details.csv
C:\Users\asweigart\invite.docx
           

8.1.2 目前工作目錄

每個運作在計算機上的程式,都有一個“目前工作目錄”,或cwd。所有沒有從根檔案夾開始的檔案名或路徑,都假定在目前工作目錄下。利用os.getcwd()函數,可以取得目前工作路徑的字元串,并可以利用os.chdir()改變它。

>>> import os
>>> os.getcwd()
'C:\\Python34'
>>> os.chdir('C:\\Windows\\System32')
>>> os.getcwd()
'C:\\Windows\\System32'
           

這裡,目前工作目錄設定為C:\Python34,是以檔案名project.docx指向C:\Python34\project.docx。如果我們将目前工作目錄改為C:\Windows,檔案就被解釋為C:\Windows\project.docx。

如果要更改的目前工作目錄不存在,Python就會顯示一個錯誤。

8.1.3 絕對路徑與相對路徑

8.1.4 用os.makedirs()建立新檔案夾

程式可以用os.makedirs()函數建立新檔案夾(目錄)。

>>> import os
>>> os.makedirs('C:\\delicious\\walnut\\waffles')
           

這不僅将建立C:\delicious檔案夾,也會在C:\delicious下建立walnut檔案夾,并在C:\delicious\walnut中建立waffles檔案夾。也就是說,os.makedirs()将建立所有必要的中間檔案夾,目的是確定完整路徑名存在。

8.1.5 os.path子產品

os.path子產品的完整文檔在Python網站上:http://docs.python.org/3/library/os.path.html。

8.1.6 處理絕對路徑和相對路徑

os.path子產品提供了一些函數,傳回一個相對路徑的絕對路徑,以及檢查給定的路徑是否為絕對路徑。

  • 調用os.path.abspath(path)将傳回參數的絕對路徑的字元串。這是将相對路徑轉換為絕對路徑的簡便方法。
  • 調用os.path.isabs(path),如果參數是一個絕對路徑,就傳回True,如果參數是一個相對路徑,就傳回False。
  • 調用os.path.relpath(path, start)将傳回從start路徑到path的相對路徑的字元串。如果沒有提供start,就使用目前工作目錄作為開始路徑。
>>> os.path.abspath('.')
'C:\\Python34'
>>> os.path.abspath('.\\Scripts')
'C:\\Python34\\Scripts'
>>> os.path.isabs('.')
False
>>> os.path.isabs(os.path.abspath('.'))
True
           

調用os.path.dirname(path)将傳回一個字元串,它包含path參數中最後一個斜杠之前的所有内容。調用os.path.basename(path)将傳回一個字元串,它包含path 參數中最後一個斜杠之後的所有内容。

如果同時需要一個路徑的目錄名稱和基本名稱,就可以調用os.path.split(),獲得這兩個字元串的元組,像這樣:

>>> calcFilePath = 'C:\\Windows\\System32\\calc.exe'
>>> os.path.split(calcFilePath)
('C:\\Windows\\System32', 'calc.exe')
           
>>> calcFilePath.split(os.path.sep)
['C:', 'Windows', 'System32', 'calc.exe']
           

8.1.7 檢視檔案大小和檔案夾内容

調用os.path.getsize(path)将傳回path參數中檔案的位元組數。

調用os.listdir(path)将傳回檔案名字元串的清單,包含path參數中的每個檔案(請注意,這個函數在os子產品中,而不是os.path)。

如果想知道這個目錄下所有檔案的總位元組數,就可以同時使用os.path.getsize()和os.listdir()。

>>> totalSize = 0
>>> for filename in os.listdir('C:\\Windows\\System32'):
     totalSize = totalSize + os.path.getsize(os.path.join('C:\\Windows\\System32', filename))
 
>>> print(totalSize)
1117846456
           

8.1.8 檢查路徑有效性

os.path子產品提供了一些函數,用于檢測給定的路徑是否存在,以及它是檔案還是檔案夾。

  • 如果path參數所指的檔案或檔案夾存在,調用os.path.exists(path)将傳回True,否則傳回False。
  • 如果path參數存在,并且是一個檔案,調用os.path.isfile(path)将傳回True,否則傳回False。
  • 如果path參數存在,并且是一個檔案夾,調用os.path.isdir(path)将傳回True,否則傳回False。

8.2 檔案讀寫過程

接下來幾節介紹的函數适用于純文字檔案。“純文字檔案”隻包含基本文本字元,不包含字型、大小和顔色資訊。帶有.txt擴充名的文本檔案,以及帶有.py擴充名的Python腳本檔案,都是純文字檔案的例子。它們可以被Windows的Notepad或OS X的TextEdit應用打開。你的程式可以輕易地讀取純文字檔案的内容,将它們作為普通的字元串值。

“二進制檔案”是所有其他檔案類型,諸如字處理文檔、PDF、圖像、電子表格和可執行程式。如果用Notepad或TextEdit打開一個二進制檔案,它看起來就像亂碼。

在Python中,讀寫檔案有3個步驟:

1.調用open()函數,傳回一個File對象。

2.調用File對象的read()或write()方法。

3.調用File對象的close()方法,關閉該檔案。

8.2.1 用open()函數打開檔案

>>> helloFile = open('C:\\Users\\_your_home_folder_\\hello.txt')
           

指令都将以讀取純文字檔案的模式打開檔案,或簡稱為“讀模式”。當檔案以讀模式打開時,Python隻讓你從檔案中讀取資料,你不能以任何方式寫入或修改它。在Python中打開檔案時,讀模式是預設的模式。但如果你不希望依賴于Python的預設值,也可以明确指明該模式,向open()傳入字元串'r',作為第二個參數。

調用open()将傳回一個File對象。File對象代表計算機中的一個檔案,它隻是Python中另一種類型的值,就像你已熟悉的清單和字典。

8.2.2 讀取檔案内容

既然有了一個File對象,就可以開始從它讀取内容。如果你希望将整個檔案的内容讀取為一個字元串值,就使用File對象的read()方法。

或者,可以使用readlines()方法,從該檔案取得一個字元串的清單。清單中的每個字元串就是文本中的每一行。

8.2.3 寫入檔案

寫模式将覆寫原有的檔案,從頭開始,就像你用一個新值覆寫一個變量的值。将'w'作為第二個參數傳遞給open(),以寫模式打開該檔案。不同的是,添加模式将在已有檔案的末尾添加文本。你可以認為這類似向一個變量中的清單添加内容,而不是完全覆寫該變量。将'a'作為第二個參數傳遞給open(),以添加模式打開該檔案。

如果傳遞給 open()的檔案名不存在,寫模式和添加模式都會建立一個新的空檔案。在讀取或寫入檔案後,調用close()方法,然後才能再次打開該檔案。

8.3 用shelve子產品儲存變量

利用shelve子產品,你可以将Python程式中的變量儲存到二進制的shelf檔案中。這樣,程式就可以從硬碟中恢複變量的資料。shelve子產品讓你在程式中添加“儲存”和“打開”功能。例如,如果運作一個程式,并輸入了一些配置設定,就可以将這些設定儲存到一個shelf檔案,然後讓程式下一次運作時加載它們。

>>> import shelve
>>> shelfFile = shelve.open('mydata')
>>> cats = ['Zophie', 'Pooka', 'Simon']
>>> shelfFile['cats'] = cats
>>> shelfFile.close()
           

要利用shelve子產品讀寫資料,首先要導入它。調用函數shelve.open()并傳入一個檔案名,然後将傳回的值儲存在一個變量中。可以對這個變量的shelf值進行修改,就像它是一個字典一樣。當你完成時,在這個值上調用close()。這裡,我們的shelf值儲存在shelfFile中。我們建立了一個清單cats,并寫下shelfFile['cats'] =cats,将該清單儲存在shelfFile中,作為鍵'cats'關聯的值(就像在字典中一樣)。然後我們在shelfFile上調用close()。

你的程式稍後可以使用shelve子產品,重新打開這些檔案并取出資料。shelf值不必用讀模式或寫模式打開,因為它們在打開後,既能讀又能寫。

就像字典一樣,shelf值有keys()和values()方法,傳回shelf中鍵和值的類似清單的值。因為這些方法傳回類似清單的值,而不是真正的清單,是以應該将它們傳遞給list()函數,取得清單的形式。

>>> shelfFile = shelve.open('mydata')
>>> list(shelfFile.keys())
['cats']
>>> list(shelfFile.values())
[['Zophie', 'Pooka', 'Simon']]
>>> shelfFile.close()
           

8.4 用pprint.pformat()函數儲存變量

回憶一下5.2節“漂亮列印”中,pprint.pprint()函數将清單或字典中的内容“漂亮列印”到螢幕,而pprint.pformat()函數将傳回同樣的文本字元串,但不是列印它。這個字元串不僅是易于閱讀的格式,同時也是文法上正确的Python代碼。假定你有一個字典,儲存在一個變量中,你希望儲存這個變量和它的内容,以便将來使用。pprint.pformat()函數将提供一個字元串,你可以将它寫入.py檔案。該檔案将成為你自己的子產品,如果你需要使用存儲在其中的變量,就可以導入它。

8.5-8.6項目