給妹子講python-S01E09 python檔案操作小意思

醬油哥在掘金發表於2019-01-16

歡迎關注公眾號:python資料科學家

【要點搶先看】

1.檔案操作模式,他的本質是字串
2.檔案的讀方法和檔案迭代器逐行掃描
3.檔案的關閉與重新整理
4.二進位制檔案的讀寫與物件的檔案儲存

前面幾集裡,我們詳細介紹了python字串以及編解碼的有關內容,這些內容實質上也是檔案操作的基礎。今天這一集,我們就正好來說說檔案操作。

先預熱一下,看一個利用open函式開啟檔案的簡單例子:

myfile = open(`myfile.txt`,`w`)
myfile = open(`myfile.txt`,`r`)
複製程式碼

【妹子說】檔案讀寫應該有很多種模式,比如只讀、可讀可寫等等,應該如何實現?

我們可以看出,利用內建函式open進行檔案操作時,第一個引數是檔名,第二個引數是處理模式。典型的使用模式引數有:r為以只讀模式開啟檔案,w為輸出模式開啟檔案,a代表在檔案尾部追加內容而開啟檔案,模式字串尾部加上b可以進行二進位制資料處理。

內建open函式會建立一個python檔案物件,作為檔案操作的介面。

我們需要牢記一點:檔案的內容是字串。從檔案讀取的資料經過函式返回時是一個字串,如果字串不是你所需的,比如你其實需要的是一個浮點數,你就需要將字串轉換為浮點數型別,而把資料寫入檔案時,也必須傳遞一個已經格式化的字串給write方法。

【妹子說】那還是老套路,舉幾個實際的例子看看:

OK,我們來看看實際使用檔案的例子:我們在檔案中寫入兩行字串(包含了換行),然後利用幾種不同的方法將其讀出,首先寫入資料:

myfile = open(`myfile.txt`,`w`)
myfile.write(`hello text file `)
myfile.write(`goodbyt text file `)
myfile.close()
複製程式碼

首先使用的是readline方法,一次手動讀取一行,最後一次返回一個空字串,意味著已經到達了檔案底部

myfile = open(`myfile.txt`,`r`)
print(myfile.readline())
print(myfile.readline())
print(myfile.readline())

hello text file
goodbyt text file
複製程式碼

其次,也可以使用read方法一次性讀取全部的檔案內容

myfile = open(`myfile.txt`,`r`)
print(myfile.read())

hello text file
goodbyt text file
複製程式碼

最後再看一種更加python的方法,可以一行一行的自動掃描檔案

myfile = open(`myfile.txt`,`r`)
for line in myfile:
    print(line, end=``)

hello text file
goodbyt text file
複製程式碼

這個方法涉及到了檔案迭代器的概念,open方法建立的檔案物件myfile將自動在每次迴圈迭代的時候讀入並返回新的一行資料。這種形式通常很容易編寫,可以很好的使用記憶體,且執行速度快。

關於迭代器的概念,我們在後續會專題介紹,這裡只用記住:利用檔案迭代器這種方法進行逐行資料讀取,是最方便的。

我們再說說二進位制檔案的讀寫操作。需要記住的是我們必須使用bytes字串處理二進位制檔案。因為當我們讀取一個二進位制資料檔案的時候,得到的是一個bytes物件,二進位制檔案不會對資料執行任何轉換。

提醒一下,對於二進位制檔案,不能以文字模式開啟,因為文字檔案實現了unicode編碼,若將二進位制檔案的內容進行unicode解碼,顯然毫無意義,同時還可能會失敗。上一小節我們談過這個問題,這裡就不多講了,我們只回顧一個例子就可以了,

myfile = open(`data.bin`,`wb`)
myfile.write(b`abcdefg`)
myfile.close()

data = open(`data.bin``rb`).read()
print(data)
print(list(data))

b`abcdefg`
[979899100101102103]
複製程式碼

再來簡單說說檔案的關閉與重新整理

檔案的關閉。呼叫檔案close方法將會終止對外部檔案的連結,即手動關閉檔案。如在檔案不再使用的時候,這個檔案物件的記憶體空間就會被收回,雖然python也有自動關閉檔案的特性,但是手動關閉是一個最為保險的方法。後面會專門介紹檔案物件的上下文管理器,他可以自動地關閉檔案。

預設情況下,檔案總是帶有緩衝的,這意味著寫入的文字可能不會立即自動從記憶體轉換到硬碟。而關閉一個檔案,或者執行flush方法,可以迫使快取的資料立即進入硬碟。

相較於之前字串形式的檔案,我們最後來講講一種特殊的檔案儲存方式:物件儲存

pickle模組是能夠讓我們直接在檔案中儲存幾乎任何python物件的高階工具,也並不要求我們把字串轉換來轉換去,他是一個通用的資料格式化和解析工具,我們舉個例子,在檔案中直接儲存一個字典物件和一個列表物件

import pickle
D = {`a`1`b`2`c`3}
L = [345]
with open(`datafile.pkl``wb`as file:
    pickle.dump(D, file)
    pickle.dump(L, file)
複製程式碼

這樣就很簡單的把兩個物件儲存在指定的檔案中了,想要取用這些物件,只需簡單的進行物件重建即可

with open(`datafile.pkl``rb`) as file:
    print(pickle.load(file))
    print(pickle.load(file))

{`b`2`a`1`c`3}
[345]
複製程式碼

Pickle模組執行的所謂物件序列化,本質上就是pickle內部字典物件、列表物件與位元組字串之間的轉換過程。

還有一種struct工具,處理打包的二進位制檔案,這裡簡單的提一下,有個印象就好,struct工具能夠構造並解析打包的二進位制資料。從某種意義上來說,它也是一種資料轉換工具。

首先我們來看如何將資料打包成二進位制資料,並儲存在檔案中,第一個引數是格式化字串,>表示高位在前、一個4位元組整數、一個5位元組字串、一個浮點數的格式。

import struct

F = open(`data.bin``wb`)
data = struct.pack(`>i5sf`8, b`abcde`4.3)
print(data)
F.write(data)
F.close()


F = open(`data.bin``rb`)
data = F.read()
print(data)
values = struct.unpack(`>i5sf`, data)
print(values)

b`x00x00x00x08abcde@x89x99x9a`
b`x00x00x00x08abcde@x89x99x9a`
(8, b`abcde`4.300000190734863)
複製程式碼

後半部分很容易理解,就是讀取檔案中的位元組字串,並用相同的格式將其解壓出來就可以了,python直接將其轉換為普通的Python物件

但是,我想說的是,一般來說二進位制檔案處理模式是用於處理更簡單的二進位制檔案,例如圖片和音訊檔案,是不需要解壓它的內容的。同時若想儲存資料,還是多使用資料庫吧。

【妹子說】恩,當今天為止,我們學習了python中的幾種主要的資料型別:列表、字典、元組和字串。在基本資料型別的基礎上,進一步瞭解了容器中的高階概念—迭代和列表解析式以及字串裡的重難點—字元編碼與檔案訪問。要好好整理複習呀~

公眾號二維碼:python資料科學家:

給妹子講python-S01E09 python檔案操作小意思

相關文章