1三、文件讀寫操做

因爲文件讀寫時都有可能產生IOError,一旦出錯,後面的f.close()就不會調用。因此,爲了保證不管是否出錯都能正確地關閉文件,咱們可使用try ... finally來實現:python

try: f = open('/path/to/file', 'r') print(f.read()) finally: if f: f.close() 

可是每次都這麼寫實在太繁瑣,因此,Python引入了with語句來自動幫咱們調用close()方法:npm

with open('/path/to/file', 'r') as f: print(f.read()) 

這和前面的try ... finally是同樣的,可是代碼更佳簡潔,而且沒必要調用f.close()方法。vim

調用read()會一次性讀取文件的所有內容,若是文件有10G,內存就爆了,因此,要保險起見,能夠反覆調用read(size)方法,每次最多讀取size個字節的內容。另外,調用readline()能夠每次讀取一行內容,調用readlines()一次讀取全部內容並按行返回list。所以,要根據須要決定怎麼調用。api

若是文件很小,read()一次性讀取最方便;若是不能肯定文件大小,反覆調用read(size)比較保險;若是是配置文件,調用readlines()最方便:app

二進制文件

前面講的默認都是讀取文本文件,而且是UTF-8編碼的文本文件。要讀取二進制文件,好比圖片、視頻等等,用'rb'模式打開文件便可:ssh

>>> f = open('/Users/michael/test.jpg', 'rb') >>> f.read() b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六進制表示的字節 

字符編碼

要讀取非UTF-8編碼的文本文件,須要給open()函數傳入encoding參數,例如,讀取GBK編碼的文件:函數

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk') >>> f.read() '測試' 

遇到有些編碼不規範的文件,你可能會遇到UnicodeDecodeError,由於在文本文件中可能夾雜了一些非法編碼的字符。遇到這種狀況,open()函數還接收一個errors參數,表示若是遇到編碼錯誤後如何處理。最簡單的方式是直接忽略:測試






>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')

操做文件和目錄

操做文件和目錄的函數一部分放在os模塊中,一部分放在os.path模塊中,這一點要注意一下。查看、建立和刪除目錄能夠這麼調用:編碼

# 查看當前目錄的絕對路徑: >>> os.path.abspath('.') '/Users/michael' # 在某個目錄下建立一個新目錄,首先把新目錄的完整路徑表示出來: >>> os.path.join('/Users/michael', 'testdir') '/Users/michael/testdir' # 而後建立一個目錄: >>> os.mkdir('/Users/michael/testdir') # 刪掉一個目錄: >>> os.rmdir('/Users/michael/testdir') 

把兩個路徑合成一個時,不要直接拼字符串,而要經過os.path.join()函數,這樣能夠正確處理不一樣操做系統的路徑分隔符。在Linux/Unix/Mac下,os.path.join()返回這樣的字符串:url

part-1/part-2

而Windows下會返回這樣的字符串:

part-1\part-2

一樣的道理,要拆分路徑時,也不要直接去拆字符串,而要經過os.path.split()函數,這樣能夠把一個路徑拆分爲兩部分,後一部分老是最後級別的目錄或文件名:

>>> os.path.split('/Users/michael/testdir/file.txt') ('/Users/michael/testdir', 'file.txt') 

os.path.splitext()能夠直接讓你獲得文件擴展名,不少時候很是方便:

>>> os.path.splitext('/path/to/file.txt') ('/path/to/file', '.txt') 

這些合併、拆分路徑的函數並不要求目錄和文件要真實存在,它們只對字符串進行操做。

文件操做使用下面的函數。假定當前目錄下有一個test.txt文件:

# 對文件重命名: >>> os.rename('test.txt', 'test.py') # 刪掉文件: >>> os.remove('test.py') 

可是複製文件的函數竟然在os模塊中不存在!緣由是複製文件並不是由操做系統提供的系統調用。理論上講,咱們經過上一節的讀寫文件能夠完成文件複製,只不過要多寫不少代碼。

幸運的是shutil模塊提供了copyfile()的函數,你還能夠在shutil模塊中找到不少實用函數,它們能夠看作是os模塊的補充。

最後看看如何利用Python的特性來過濾文件。好比咱們要列出當前目錄下的全部目錄,只須要一行代碼:

>>> [x for x in os.listdir('.') if os.path.isdir(x)] ['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...] 

要列出全部的.py文件,也只需一行代碼:

>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py'] ['apis.py', 'config.py', 'models.py', 'pymonitor.py', 'test_db.py', 'urls.py', 'wsgiapp.py']
相關文章
相關標籤/搜索