那些年,我們一起看的例外
Click here to load reader
-
Upload
kao-kuo-tung -
Category
Technology
-
view
456 -
download
1
description
Transcript of 那些年,我們一起看的例外
那些年,我們一起看的例外
果凍
about me● web backend developer● interest in:
○ operator system○ programming language
● http://about.me/ya790206
先看個例外
Traceback (most recent call last): File "b.py", line 14, in <module> print func(lst, a) File "b.py", line 8, in func raise MyIndexException("list index out of range")__main__.MyIndexException: list index out of range
那個例外所對應的程式碼import pickleclass Exception(Exception): pass
def func(lst, index): if index < len(lst): return lst[index] raise MyIndexException("list index out of range")
a = input()with open('data.txt', 'r') as ftr: lst = pickle.load(ftr) print func(lst, a)
例外告訴我們什麼?
1. 在 b.py 第 8 行(在 func)出錯。原因是 list index out of range。
2. 在 b.py 第 14 行(在 func)呼叫3. 例外的類型是 __main__.MyIndexException
心中疑惑
● lst 元素到底有幾個,還是根本沒有元素?● a 那個數字到底多大?
方法一import pickleclass Exception(Exception): pass
def func(lst, index): if index < len(lst): return lst[index] raise MyIndexException("list index out of range" +str(locals()))
a = input()with open('data.txt', 'r') as ftr: lst = pickle.load(ftr) print func(lst, a)
真的吐出區域變數的資訊了
Traceback (most recent call last): File "c.py", line 14, in <module> print func(lst, a) File "c.py", line 8, in func raise MyIndexException("list index out of range. " + str(locals()))__main__.MyIndexException: list index out of range. {'index': 8, 'lst': [1, 2, 3]}
● 這程式碼看起來很有點蠢● 有沒有更好的辦法?
在例外建構子做一些手腳,方法二
import pickleimport inspectclass MyIndexException(Exception): def __init__(self, msg): msg += str(inspect.stack()[1][0].f_locals) super(MyIndexException, self).__init__(msg)
下略 ...
效果等價方法一,更好用了
Traceback (most recent call last): File "c.py", line 14, in <module> print func(lst, a) File "c.py", line 8, in func raise MyIndexException("list index out of range. " + str(locals()))__main__.MyIndexException: list index out of range. {'index': 8, 'lst': [1, 2, 3]}
● 這一切看起來很美好。也只有看起來。● 如果 ... 程式碼變這樣?
如果例外是內建的例外 ...
import pickledef func(lst, index): return lst[index]a = input()with open('data.txt', 'r') as ftr: lst = pickle.load(ftr) print func(lst, a)
如果例外是內建的例外 ...
Traceback (most recent call last): File "a.py", line 11, in <module> print func(lst, a) File "a.py", line 5, in func return lst[index]IndexError: list index out of range
How to solve it?
● 如果你想修改 IndexError 的建構子的話● 你需要修改 python source code,並自己編譯
他 …● It’s hard for me.
其他解,方法三
● 利用 trace function 追蹤○ https://github.
com/ya790206/log_exception/blob/master/log_exception.py
○ 無法和 pdb 共存○ 會降低 python 效能,因此不適用於
production。
其他可能解
● monkey patch 所有內建例外?
總結
● 方法一:程式碼有點醜陋。每次都要傳參數進去有點麻煩。
● 方法二:只有當錯誤發生時,才自動做紀錄。可避免方法三的效能問題。但要注意上一個的 call stack 未必是你要的資料。如子類別 override 建構子時。又此法只能用在自訂類別。
總結
● 方法三:可以印出所有例外發生時的 call stack 資訊。缺點為嚴重影響效能。只適合用在開發時期。
設計緣由
為什麼我會希望把錯誤當時的 run time 資訊顯示出來? bug 可以分成三種:一種是程式錯誤,一種是資料錯誤,一種是前兩者都是錯的。過去維護的一個系統,裡面資料很多都是錯的。因此每當客戶回報系統有問題時,需要花時間去釐清哪種錯誤。如果能夠取得錯誤時的 run time 資訊,可以加速重建錯誤的情形,以利除錯。