從零開始學Python(七):檔案儲存I/O流和異常捕捉

momoxiaomming發表於2018-02-03

這兩天在搞小程式開發,耽擱了一下更新的進度,今天補上.一個完整的前端程式肯定離不開資料儲存和網路兩個模組,今天我們就先來講講python中的一種常見資料儲存:檔案儲存!~!

檔案儲存(I/O操作)

何為I/O?

I/O分別對應著英文input和output的縮寫,代表著輸入和輸出.分別對應著我們檔案的讀和寫的過程,

當我們對一個檔案進行讀取的操作的時候,程式會以我們要讀取的檔案為目標,通過輸入流操作,將文字讀取到快取區,以便以後呼叫.

當我們對一個檔案進行寫的操作的時候,程式會將我們存在緩衝區中的資料通過輸出流寫到我們的目標檔案裡.

Python的鍵盤輸入

python中等待鍵盤的函式有兩個,raw_input和input,兩者作用效果相同,記錄鍵盤的輸入並返回結果.

s=raw_input('請輸入任意內容:\n')

print '輸出:'+s

>>>請輸入任意內容:
	hello
	輸出:hello
複製程式碼

raw_input函式返回的是一個字串物件,我們可以直接列印出輸入結果.

s=input('請輸入任意內容:\n')

print '輸出:',s

>>>請輸入任意內容:
	5*6
	輸出: 30
複製程式碼

input函式返回的是一個物件,他和raw_input的根本區別是可以輸入表示式,並且返回表示式的結果.

Python檔案操作

Python的檔案操作都是由file物件處理.

open函式

file object = open(file_name [, access_mode][, buffering])
複製程式碼

Python提供了內建函式open來獲取file物件,這裡我們仔細的講解一下相關此引數的作用.

  • file_name 檔案路徑.代表著我們要寫入的檔名或者我們要讀取的檔案,注意:這裡的路徑是相對路徑,相對於我們程式所在目錄的路徑
  • access_mode 開啟檔案的模式.可不填,預設為只讀.也可根據需求改變,以下是全部的模式.
模式 說明
r 以只讀方式開啟檔案。檔案的指標將會放在檔案的開頭。這是預設模式。
rb 以二進位制格式開啟一個檔案用於只讀。檔案指標將會放在檔案的開頭。這是預設模式。
r+ 開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。
rb+ 以二進位制格式開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。
w 開啟一個檔案只用於寫入。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
wb 以二進位制格式開啟一個檔案只用於寫入。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
w+ 開啟一個檔案用於讀寫。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
wb+ 以二進位制格式開啟一個檔案用於讀寫。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
a 開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
ab 以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
a+ 開啟一個檔案用於讀寫。如果該檔案已存在,檔案指標將會放在檔案的結尾。檔案開啟時會是追加模式。如果該檔案不存在,建立新檔案用於讀寫。
ab+ 以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。如果該檔案不存在,建立新檔案用於讀寫。
  • buffering 用於設定快取策略 在二進位制模式下,使用0來切換緩衝;在文字模式下,通過1表示行緩衝(固定大小的緩衝區)。 在不給引數的時候,二進位制檔案的緩衝區大小由底層裝置決定,可以通過io.DEFAULT_BUFFER_SIZE獲取,通常為4096或8192位元組

我們簡單的舉個例子:(test.py檔案程式碼)

test.py檔案程式碼,f/b

f=open('f/b.txt')   #我們讀取本模組目錄下的f資料夾中的b.txt檔案,其他兩個引數預設
print f
prin io.DEFAULT_BUFFER_SIZE
>>> <open file 'f/b.txt', mode 'r' at 0x1028581e0>  #可以發現檔案物件預設模式是r
	8192   #裝置預設緩衝區為8192位元組(注意,這裡需要匯入io模組才可使用io函式)
複製程式碼

File物件相關函式

通過Python的open函式我們可以得到File物件,而檔案儲存的操作就是針對file物件來進行的. file物件有幾個常用的函式,下面我們來一一講解:

close函式

close函式的作用是重新整理緩衝區.並關閉file物件的操作流,此後便不能再進行讀寫操作了.當這個file物件再指定到新的檔案物件時,file物件會先關閉以前的檔案物件.所以,當我們對一個檔案操作完畢之後,應當養成良好的關閉習慣,也就是呼叫close函式

f=open('f/b.txt')
f.close()
複製程式碼
write函式

write函式是file物件的資料寫入函式,通過該函式可以將我們的字串資料或者二進位制資料寫入到資料夾中.需要注意的是,如果我們需要資料換行,要另外寫入換行符. 該函式需要有檔案的寫許可權

f=open('f/b.txt','a+')  #這裡我們制定了檔案模式是讀寫模式(具體可參考上面的表),並且指標放在末尾

f.write('我是一個小小的python愛好者,我在學習python') 
f.write('雖然學習之路艱辛\n但我不放棄')  #注意這裡我們中間加了一個換行符
f.close()  #操作完畢關閉物件
複製程式碼

執行以上程式碼之後,你可以去相關目錄開啟b.txt檔案檢視內容:(但我不放棄這句因為換行單獨成一行了)

我是一個小小的python愛好者,我在學習python雖然學習之路艱辛
但我不放棄
複製程式碼
read函式
f.read(n)  #引數n表示讀取的檔案長度,這裡的長度是位元組長度,引數不填的時候預設為預設緩衝區大小,上面我們列印過,是8192個位元組長度
複製程式碼

Tips:一個gbk編碼的漢字佔二個位元組,一個utf-8編碼的漢字佔三個位元組.(所以要想輸出一個完整的utf-8的字元,最少長度要為3)

read是從一個開啟的檔案物件中讀取資料.

f=open('f/b.txt','a+')
f.seek(0)    #seek是定位函式,由於我們使用了a+檔案模式,導致檔案操作指標永遠在最後面,而最後面是沒有資料的,所以我們將游標恢復到開頭,這樣我們就可能讀取到資料了.
str=f.read()  #
f.close()
print str

>>> 我是一個小小的python愛好者,我在學習python雖然學習之路艱辛
	但我不放棄
複製程式碼

其實read函式還有幾個衍生的方法,比如readline,讀取一行,大家可以自己試試.

seek和tell函式

seek()和tell()是兩個檔案定位函式,一個是設定檔案的操作位置,一個是獲取檔案的操作位置(注意:我們平常的檔案讀寫操作都是會改變檔案的操作位置的),有時候我們可能需要在某一段字串的中間插入一端字串,這時我們就可以利用定位函式來達到我們的需求.

f=open('f/b.txt','r+')
f.seek(0)    #設定游標從0開始讀
str=f.read(27)  
print str   
f.seek(27)   #設定從位置27位元組開始寫
f.write('哈哈哈')
f.close()

>>> 我是一個小小的python哈哈哈,我在學習python雖然學習之路艱辛
	但我不放棄
複製程式碼

上面的例子中,我們直接在中間插入了'哈哈哈'字元

檔案刪除

檔案刪除我們需要用到python的os模組,使用時需要匯入該模組.

使用os模組的remove方法開始刪除

os.remove(filepath)    #引數傳我們需要刪除的檔案路徑
複製程式碼

以上就是我們檔案操作,從建立,讀寫,到刪除的整個過程,當然我們因為是入門篇,只是介紹了最基本的用法,不過萬事不變其宗,基礎牢固了,我們才能更好的向外擴充!學習之路慢慢其修遠兮!

Python異常

什麼是異常

異常即是一個事件,該事件會在程式執行過程中發生,影響了程式的正常執行。 一般情況下,在Python無法正常處理程式時就會發生一個異常。 異常是Python物件,表示一個錯誤。 當Python指令碼發生異常時我們需要捕獲處理它,否則程式會終止執行。

當我們的程式出現錯誤的時候,編譯器都會告訴我們錯誤的地方,可是當我們程式上線之後,一旦遇到錯誤,程式便會當機,這是我們不能容忍的,這時候就需要用到異常處理了.

python標準異常

首先我們來看個表,裡面基本羅列了python中我們所有會遇到的異常(不用一一記住,腦袋過一遍就可以了):

異常名稱 異常描述
BaseException 所有異常的基類
SystemExit 直譯器請求退出
KeyboardInterrupt 使用者中斷執行(通常是輸入^C)
Exception 常規錯誤的基類
StopIteration 迭代器沒有更多的值
GeneratorExit 生成器(generator)發生異常來通知退出
StandardError 所有的內建標準異常的基類
ArithmeticError 所有數值計算錯誤的基類
FloatingPointError 浮點計算錯誤
OverflowError 數值運算超出最大限制
ZeroDivisionError 除(或取模)零 (所有資料型別)
AssertionError 斷言語句失敗
AttributeError 物件沒有這個屬性
EOFError 沒有內建輸入,到達EOF 標記
EnvironmentError 作業系統錯誤的基類
IOError 輸入/輸出操作失敗
OSError 作業系統錯誤
WindowsError 系統呼叫失敗
ImportError 匯入模組/物件失敗
LookupError 無效資料查詢的基類
IndexError 序列中沒有此索引(index)
KeyError 對映中沒有這個鍵
MemoryError 記憶體溢位錯誤(對於Python 直譯器不是致命的)
NameError 未宣告/初始化物件 (沒有屬性)
UnboundLocalError 訪問未初始化的本地變數
ReferenceError 弱引用(Weak reference)試圖訪問已經垃圾回收了的物件
RuntimeError 一般的執行時錯誤
NotImplementedError 尚未實現的方法
SyntaxError Python 語法錯誤
IndentationError 縮排錯誤
TabError Tab 和空格混用
SystemError 一般的直譯器系統錯誤
TypeError 對型別無效的操作
ValueError 傳入無效的引數
UnicodeError Unicode 相關的錯誤
UnicodeDecodeError Unicode 解碼時的錯誤
UnicodeEncodeError Unicode 編碼時錯誤
UnicodeTranslateError Unicode 轉換時錯誤
Warning 警告的基類
DeprecationWarning 關於被棄用的特徵的警告
FutureWarning 關於構造將來語義會有改變的警告
OverflowWarning 舊的關於自動提升為長整型(long)的警告
PendingDeprecationWarning 關於特性將會被廢棄的警告
RuntimeWarning 可疑的執行時行為(runtime behavior)的警告
SyntaxWarning 可疑的語法的警告
UserWarning 使用者程式碼生成的警告

異常的捕捉和處理

python中的異常捕捉處理和java或者oc差不多.都是一個程式碼塊:

try:
	#可能會出現異常的程式碼
except Exception as e:
	#出現異常的資訊,這裡我們可以將錯誤資訊上傳
else:
	#如果沒有異常發生
finally:
	#這裡的程式碼不管出不出現異常都會呼叫,可以用來做一些檔案關閉,索引關閉的操作
複製程式碼

我們來做個簡單的異常捕捉的例子:

f=None
try:
	f = open('f/b.txt', 'r+')  #這裡我們開啟一個f目錄下的b.txt檔案,其實這個檔案是不存在的,應該會發生異常
except Exception as e:   #這裡我們使用的是異常的基類,可以先刪除所有異常,畢竟有時候我們也不知道到底發生的異常是屬於哪個類(當然,精確點總是更好的)
	print e   #我們將異常列印出來

finally:
	if f:
    	f.close()    #不管發沒發生異常,我們都希望f物件存在的時候要關閉操作
    	
>>>  [Errno 2] No such file or directory: 'f/b.txt'   #確實發生了檔案或者目錄找不到的異常
複製程式碼

以上就是異常的的常用用法,是不是很簡單,日常開發中,我們可能會遇到很多異常處理,我們需要根據自己的需求對程式碼塊進行更改,以便以我們的程式碼可以抗拒任何惡劣的環境.

Q&A

到這裡,我們這一章就講完了.到了這裡,我們已經算是入門了,基本的python語法,物件,函式,寫法,我們都已經學會了,下一章開始,我們學習一點更加深一點的東西,多執行緒

相關文章