那些年,我們一起看
的例外
果凍
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...
那個例外所對應的程式碼
import pickle
class Exception(Exception):
pass
def func(lst, index):
if index < len(lst):
return lst[index]
ra...
例外告訴我們什麼?
1. 在 b.py 第 8 行(在 func)出錯。原因是 list
index out of range。
2. 在 b.py 第 14 行(在 func)呼叫
3. 例外的類型是 __main__.MyIndexExce...
心中疑惑
● lst 元素到底有幾個,還是根本沒有元素?
● a 那個數字到底多大?
方法一
import pickle
class Exception(Exception):
pass
def func(lst, index):
if index < len(lst):
return lst[index]
raise MyIn...
真的吐出區域變數的資訊了
Traceback (most recent call last):
File "c.py", line 14, in <module>
print func(lst, a)
File "c.py", line 8, ...
● 這程式碼看起來很有點蠢
● 有沒有更好的辦法?
在例外建構子做一些手腳,方法二
import pickle
import inspect
class MyIndexException(Exception):
def __init__(self, msg):
msg += str(inspec...
效果等價方法一,更好用了
Traceback (most recent call last):
File "c.py", line 14, in <module>
print func(lst, a)
File "c.py", line 8, ...
● 這一切看起來很美好。也只有看起來。
● 如果 ... 程式碼變這樣?
如果例外是內建的例外 ...
import pickle
def func(lst, index):
return lst[index]
a = input()
with open('data.txt', 'r') as ftr:
lst = ...
如果例外是內建的例外 ...
Traceback (most recent call last):
File "a.py", line 11, in <module>
print func(lst, a)
File "a.py", line 5...
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 共存
○ 會...
其他可能解
● monkey patch 所有內建例外?
總結
● 方法一:程式碼有點醜陋。每次都要傳參數進
去有點麻煩。
● 方法二:只有當錯誤發生時,才自動做紀錄。可
避免方法三的效能問題。但要注意上一個的
call stack 未必是你要的資料。如子類別
override 建構子時。又此法只能用...
總結
● 方法三:可以印出所有例外發生時的 call stack
資訊。缺點為嚴重影響效能。只適合用在開發
時期。
設計緣由
為什麼我會希望把錯誤當時的 run time 資訊顯
示出來? bug 可以分成三種:一種是程式錯誤,
一種是資料錯誤,一種是前兩者都是錯的。過去
維護的一個系統,裡面資料很多都是錯的。因此
每當客戶回報系統有問題時,需要花時間去釐清...
Upcoming SlideShare
Loading in …5
×

那些年,我們一起看的例外

693 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
693
On SlideShare
0
From Embeds
0
Number of Embeds
187
Actions
Shares
0
Downloads
3
Comments
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 資 訊,可以加速重建錯誤的情形,以利除錯。

×