Upcoming SlideShare
×

# 那些年，我們一起看的例外

693 views

Published on

Published in: Technology
0 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

• Be the first to like this

Views
Total views
693
On SlideShare
0
From Embeds
0
Number of Embeds
187
Actions
Shares
0
3
0
Likes
0
Embeds 0
No embeds

No notes for slide

### 那些年，我們一起看的例外

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