一、學IO操作目的是啥?
我們在編程時一般不可能只是打打代碼,而沒有將數據存到電腦上,比如想把一篇文章寫在電腦裏,或者想從電腦中查看一篇文章,那就需要IO流操作,將文章永久存到電腦上。可能很多讀者都不明白,不是就簡單的複製粘貼嘛,哪有那麼高級。這裏牛頓就會冒出來說那是你站在巨人的肩膀上,沒錯!我們一般用到的都是簡單化的讀寫,你想想我們的複製粘貼哪裏來?就是我們在軟件內部寫了IO流操作,把事情簡單化了,使得我們不用考慮到這麼多知識,而是簡單的複製粘貼。哪有的人又問,Print函數和Input函數表示就是輸入輸出嗎?是的,但是我們不可能讓用戶去編寫一段代碼吧,肯定需要讓用戶操作的越簡單越好啦!再加上電腦已關機,輸入的文字就會隨之消失!
那什麼是IO流操作呢?
首先我們需要清楚IO流操作中的讀寫操作不是我們平時所說讀寫看,而是將數據加載到硬盤中,我們叫IO流的寫操作,即輸入流,將硬盤加載出來,叫做IO流的讀操作,即輸出流。
那問題來了,什麼是流?
流是個比較抽象的概念,可以這麼理解,假設硬盤是大海,那麼數據流就可以是水流,水要進入大海就是輸入流,水要流出來就是輸出流。字節流就是一滴一滴地流,字符流就是一大塊一大塊地流,區別嘛,就是字節流變得更加簡單和純淨,而字符流,什麼垃圾啊,魚啊,一起加進去流動。
流操作分類
1.按照數據流方向可以分爲輸入流和輸出流。
2.按照處理數據類型的單位不同可以分爲字節流和字符流。
所以IO流操作就是一種抽象的概念,即Input Output Stream,輸入輸出流,以流的方式進行輸入輸出。
一個完整的IO操作,一般爲以下步驟:
打開文件 ==> 讀取數據 ==> 數據運算 ==> 數據的持久化 ==> 關閉資源
讀取數據是將數據從一個持久化設備(比如硬盤,U盤)中讀取到內存(這東西比硬盤快)中。
(以上是個人理解)
二、open函數
那很多人就感覺IO流應該是一隻非常難搞的鴨子!說實話,確實有點,在其他編程語言中,IO流操作一直都是一大難點之一,但是在Python中,它就是一個函數,一個內置函數,Python團隊將它簡單化了!
格式
open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file:必選參數,傳入的文件名路徑,可以是相對路徑也可以是絕對路徑。
mode:可選參數,用於指定文件的打開方式,默認爲r
。
buffering:可選參數,用於指定對文件做讀寫操作時,是否使用緩衝區(可以理解爲爲內存),爲0則表示在打開指定文件時不使用緩衝區,爲大於0的整數用於指定緩衝區的大小(單位是字節),爲小於0則代表使用默認的區大小。建議爲默認值,因爲快啊!
encoding:設定打開文件時所使用的編碼格式。
errors:可選參數,指定編碼錯誤如何處理,不在二進制模式下使用。
newline:可選參數,就是用來換行的。
closefd:可選參數,一般用不到
opener:可選參數,一般用不到
三、open函數使用
1.輸入流與輸出流
輸入流輸出流其實是和字符字節流一起套用的,就相當於一個改變的是水流方向,一個是水的容量,我們先演示的是字符流,一般情況下,字符流是不需要使用關鍵傳參的。
注意:默認爲mode="rt"
下面是mode值的參數表:
a.輸出流就是mode=“r”
代碼
#假設文件名爲China.txt 內容爲:我愛中國!也愛Python!
#由於Win系統編碼不能顯示漢字所以使用utf-8
#read函數是隻讀模式下使用的用來讀出數據,只讀模式下不可以使用write函數
#close函數是關閉文件,防止內存佔用,雖然Python默認有內存回收機制,但是以防萬一嘛!
op = open("H:\\China.txt", encoding="utf-8")
print(op.read())
op.close()
顯示結果
b.輸入流就是mode=“w"或者"a”
會發現怎麼輸入流是兩個呢?因爲"w"
表示的是將原來的覆蓋,重新寫,而"a"
是在原來的基礎上添加!
代碼
#假設文件名爲China.txt 內容:我愛中國!也愛Python!
#weite函數接收字符後,返回字符個數,只寫模式下不可以使用read函數
op_1 = open("H:\\China.txt", "a", encoding="utf-8")
op_2 = open("H:\\Python.txt", "w", encoding="utf-8")
print(op_1.write("我愛中國!也愛Python!"))
print(op_2.write("我愛中國!愛Python!"))
op_1.close()
op_2.close()
顯示結果
2.字節操作
接下來就是字節流操作,字節流操作的讀操作是輸出一堆字節,所以沒有編碼,必須將字符轉換成字節才能傳輸,就相當於小吸管不能塞進大魚一樣。
在Python中在字符引號前面加b
就是將其改變成字節。
注意:字節流操作不支持編碼參數傳參,即encoding爲默認值
字節的輸出流操作
就是mode="rb"
代碼
#假設文件名爲China.txt 內容爲:我愛中國!也愛Python!
#由於Win系統編碼不能顯示漢字所以使用utf-8
#read函數是隻讀模式下使用的用來讀出數據,只讀模式下不可以使用write函數
#close函數是關閉文件,防止內存佔用,雖然Python默認有內存回收機制,但是以防萬一嘛!
#注意字節流操作不支持編碼
op = open("H:\\China.txt", "rb")
print(op.read())
op.close()
顯示結果
字節的輸入流操作
就是mode="ab"
或者mode="wb"
代碼
#假設文件名爲China.txt 內容:字節1和13
#b在Python中表示字節,所以在字節流中只能傳字節
#weite函數接收字符後,返回字符個數,只寫模式下不可以使用read函數
op_1 = open("H:\\China.txt", "ab")
op_2 = open("H:\\Python.txt", "wb")
print(op_1.write(b'1'))
print(op_2.write(b'13'))
op_1.close()
op_2.close()
顯示結果
下面是mode參數的組合:
下面是文件對象內置方法:
四、with語句塊
with語句塊是一種從Python2.5引入的一個新的語法,它是一種上下文管理協議,目的在於從流程圖中把 try,except 和finally 關鍵字和資源分配釋放相關代碼統統去掉,簡化try…except…finlally(後面會講的異常處理)的處理流程。說白了就是對沒有關掉文件對象,默認使用close
函數,避免程序員忘記關閉。(說實話,一個字,周到!)
格式:
with expression [as target]:
…語句塊
expression:一個需要執行的表達式
target:一個變量或者元組,存儲的是expression表達式執行返回的結果,可選參數。
代碼
file_1 = open("H:\\China.txt", "r", encoding="utf-8")
with file_1 as f:
print(f.read())
顯示結果
五、對象的序列化和反序列化
對象概念是一個邏輯單位,它是比較抽象的一個概念。後面會詳細講解,目前暫時理解爲,一種黑盒子或者一種思維。
對象的序列化和反序列化也是一種抽象的概念,我們可以理解爲,一種思維實體化,就是說,一個虛無的東西變成一種可以摸得到看的到的東西,比如開心這個感覺,它是虛無,看不到也摸不着的,但是我們通過文字開心就能明白這個東西是什麼,從開心這個感覺到文字的展現的這個過程叫序列化,而反序列化,就是我們通過讀懂文字知道開心這個感覺的這個過程。簡而言之就是思維實體化。
對象序列化就是將對象這個概念變成字節數據,反之,就是反序列化。我們可以通過導入pickle
模塊的dump/dumps
方法進行序列化,load/loads
方法進行反序列化。還有json
模塊也是,但是一般用來序列化字典類型的數據。
關於json/pickle
模塊的序列化函數使用:鏈接在此
1.序列化
代碼
import pickle
list_1 = [19,2,4,69,77,8,9]
list_2 = [8,2,84,67,7,8,9]
file_1 = open("H:\\list_1.txt", "wb")
file_2 = open("H:\\list_2.txt", "wb")
data_1 = pickle.dump(list_1, file_1)
print(data_1) #返回None
file_1.close()
data_2 = pickle.dumps(list_2)
with file_2 as f:
print(f.write(data_2))
顯示結果
2.反序列化
代碼
import pickle
file_1 = open("H:\\list_1.txt", "rb")
file_2 = open("H:\\list_2.txt", "rb")
list_1 = pickle.load(file_1)
file_1.close()
with file_2 as f:
data_2 = f.read()
list_2 = pickle.loads(data_2)
print(list_1)
print(list_2)
顯示結果