譯者:飛龍
協議:cc by-nc-sa 4.0
程式設計師必須總是留意程式中可能出現的錯誤。例子數不勝數:乙個函式可能不會收到它預期的資訊,必需的資源可能會丟失,或者網路上的連線可能丟失。在設計系統時,程式設計師必須預料到可能產生的異常情況並且採取適當地措施來處理它們。
處理程式中的錯誤沒有單一的正確方式。為提供一些永續性服務而設計的程式,例如 web 伺服器 應該對錯誤健壯,將它們記錄到日誌中為之後考慮,而且在盡可能長的時間內繼續接受新的請求。另一方面,python 直譯器通過立即終止以及列印錯誤資訊來處理錯誤,便於程式設計師在錯誤發生時處理它。在任何情況下,程式設計師必須決定程式如何對異常條件做出反應。
異常是這一節的話題,它為程式的錯誤處理提供了通用的機制。產生異常是一種技巧,終止程式正常執行流,發射異常情況產生的訊號,並直接返回到用於響應異常情況的程式的封閉部分。python 直譯器每次在檢測到語句或表示式錯誤時丟擲異常。使用者也可以使用raise
或assert
語句來丟擲異常。
丟擲異常。異常是乙個物件例項,它的類直接或間接繼承自baseexception
類。第一章引入的assert
語句產生assertionerror
類的異常。通常,異常例項可以使用raise
語句來丟擲。raise
語句的通用形式在 python 文件中描述。raise
的最常見的作用是構造異常例項並丟擲它。
>>> raise exception('an error occurred')
traceback (most recent call last):
file "", line 1, in exception: an error occurred
當異常產生時,當前**塊的語句不會繼續執行。除非異常被解決了(下面會描述),直譯器會直接返回到「讀取-求值-列印」互動式迴圈中,或者在 python 以檔案引數啟動的情況下會完全終止。此外,直譯器會列印棧回溯,它是結構化的文字塊,描述了執行分支中的一系列巢狀的活動函式,它們是異常產生的位置。在上面的例子中,檔名稱
表示異常由使用者在互動式會話中產生,而不是檔案中的**。
處理異常。異常可以使用封閉的try
語句來處理。try
語句由多個子句組成,第乙個子句以try
開始,剩下的以except
開始。
try:
except as :
...
當try
語句執行時,
總是會立即執行。except
子句組只在
執行過程中的異常產生時執行。每個except
子句指定了需要處理的異常的特定類。例如,如果
是assertionerror
,那麼任何繼承自assertionerror
的類例項都會被處理,識別符號
繫結到所產生的異常物件上,但是這個繫結在
之外並不有效。
例如,我們可以使用try
語句來處理異常,在異常發生時將x
繫結為0
。
>>> try:
x = 1/0
except zerodivisionerror as e:
print('handling a', type(e))
x = 0
handling a >>> x
0
try
語句能夠處理產生在函式體中的異常,函式在
中呼叫。當異常產生時,控制流會直接跳到最近的try
語句的能夠處理該異常型別的
的主體中。
>>> def invert(x):
result = 1/x # raises a zerodivisionerror if x is 0
print('never printed if x is 0')
return result
>>> def invert_safe(x):
try:
return invert(x)
except zerodivisionerror as e:
return str(e)
>>> invert_safe(2)
never printed if x is 0
0.5>>> invert_safe(0)
'division by zero'
這個例子表明,invert
中的print
表示式永遠不會求值,反之,控制流跳到了handler
中的except
子句組中。將zerodivisionerror e
強制轉為字串會得到由handler: 'division by zero'
返回的人類可讀的字串。
異常物件本身就帶有屬性,例如在assert
語句中的錯誤資訊,以及有關異常產生處的資訊。使用者定義的異常類可以攜帶額外的屬性。
在第一章中,我們實現了牛頓法來尋找任何函式的零點。下面的例子定義了乙個異常類,無論何時valueerror
出現,它都返回迭代改進過程中所發現的最佳猜測值。數學錯誤(valueerror
的一種)在sqrt
在負數上呼叫時產生。這個異常由丟擲iterimproveerror
處理,它將牛頓迭代法的最新猜測值儲存為引數。
首先,我們定義了新的類,繼承自exception
。
>>> class iterimproveerror(exception):
def __init__(self, last_guess):
self.last_guess = last_guess
下面,我們定義了iterimprove
,我們的通用迭代改進演算法的乙個版本。這個版本通過丟擲iterimproveerror
異常,儲存最新的猜測值來處理任何valueerror
。像之前一樣,iter_improve
接受兩個函式作為引數,每個函式都接受單一的數值引數。update
函式返回新的猜測值,而done
函式返回布林值,表明改進是否收斂到了正確的值。
>>> def iter_improve(update, done, guess=1, max_updates=1000):
k = 0
try:
while not done(guess) and k < max_updates:
guess = update(guess)
k = k + 1
return guess
except valueerror:
raise iterimproveerror(guess)
最後,我們定義了find_root
,它返回iter_improve
的結果。iter_improve
應用於由newton_update
返回的牛頓更新函式。newton_update
定義在第一章,在這個例子中無需任何改變。find_root
的這個版本通過返回它的最後乙個猜測之來處理iterimproveerror
。
>>> def find_root(f, guess=1):
def done(x):
return f(x) == 0
try:
return iter_improve(newton_update(f), done, guess)
except iterimproveerror as e:
return e.last_guess
考慮使用find_root
來尋找2 * x ** 2 + sqrt(x)
的零點。這個函式的乙個零點是0
,但是在任何負數上求解它會產生valueerror
。我們第一章的牛頓法實現會產生異常,並且不能返回任何零點的猜測值。我們的修訂版實現在錯誤之前返回了最新的猜測值。
>>> from math import sqrt
>>> find_root(lambda x: 2*x*x + sqrt(x))
-0.030211203830201594
雖然這個近似值仍舊距離正確的答案0
很遠,一些應用更傾向於這個近似值而不是valueerror
。
異常是另乙個技巧,幫助我們將程式細節劃分為模組化的部分。在這個例子中,python 的異常機制允許我們分離迭代改進的邏輯,它在try
子句組中沒有發生改變,以及錯誤處理的邏輯,它出現在except
子句中。我們也會發現,異常在使用 python 實現直譯器時是個非常實用的特性。
表示和描述(3)
接上篇 表示和描述 2 主分量描述適用於邊界和區域。用在區域 影象 上可以抽取方差最大的分量 主分量 用在邊界上可以對其做縮放 平移和旋轉的歸一化。主分量 pca 一般用於資料降維,因為大特徵值對應影象細節 高頻 主分量的計算過程可歸納為 具體分析參考 由多組特徵向量計算均值向量m,由此得到協方差矩...
MPEG 7描述子 3 顏色布局描述子CLD
dct變換利用傅利葉變換的性質。採用影象邊界褶翻將像變換為偶函式形式,然後對影象進行二維傅利葉變換,變換後僅包含余弦項,所以稱之為離散余弦 變換。dct編碼屬於正交變換編碼方式,用於去除影象資料的空間冗餘。變換 編碼就是將影象光強矩陣 時域訊號 變換到係數空間 頻域訊號 上進行處理的 方法。在空間上...
3 描述性統計分析
描述定量資料的數值法 中心趨勢的度量 變異性的度量 相對位置的度量 檢測異常值的方法 reference 對給定的類,類 或組 頻數是指落入這個類中的觀測值的個數。對給定的類,類 或組 相對頻率是指落入這個類中的觀測值個數相對於觀測值總數的比例。定性資料的圖形描述常用條形圖,餅圖和帕雷託圖。條形圖 ...