編寫一個或多個異常處理程序函數,給定函數及其中引發的異常,執行您想要執行的操作(例如顯示警報)。如果你需要不止一個,請寫下來。
def message(func, e):
print "Exception", type(e).__name__, "in", func.__name__
print str(e)
現在編寫用於給定的處理程序調用的函數一個裝飾:
import functools
def handle_with(handler, *exceptions):
try:
handler, cleanup = handler
except TypeError:
cleanup = lambda f, e: None
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except exceptions or Exception as e:
return handler(func, e)
finally:
cleanup(func, e)
return wrapper
return decorator
這僅捕獲指定的異常。如果你沒有指定任何,Exception
被捕獲。此外,第一個參數可以是兩個處理函數的元組(或其他序列);第二個處理程序(如果給出)在finally
子句中調用。從主處理程序返回的值將作爲函數調用的值返回。
現在,鑑於上述情況,你可以這樣寫:
from contextlib import contextmanager
@contextmanager
def handler(handler, *exceptions):
try:
handler, cleanup = handler
except TypeError:
cleanup = lambda e: None
try:
yield
except exceptions or Exception as e:
handler(e)
finally:
cleanup(e)
現在你可以寫:
def message(e):
print "Exception", type(e).__name__
print str(e)
def add(x, y):
with handler(message, TypeError, ValueError):
return x + y
@handle_with(message, TypeError, ValueError)
def add(x, y):
return x + y
你也可以用上下文管理做到這一點請注意,上下文管理器不知道它是什麼功能(你可以找到它,使用inspect
,雖然這是「魔術」,所以我沒有這樣做),所以它給你一些不太有用的信息。此外,上下文管理器不會讓您有機會返回處理程序中的任何內容。
也許是裝飾者? – Milo
您是否需要在每種方法中實際捕捉異常?你不能在你的類方法中捕獲它們,但在調用方法的代碼中捕獲它們。 –