2013-10-07 70 views
2

我用Python編寫的程序,並且幾乎所有的即時通訊的方法我的課是這樣寫的:例外全班

def someMethod(self): 
    try: 
     #... 
    except someException: 
     #in case of exception, do something here 

     #e.g display a dialog box to inform the user 
     #that he has done something wrong 

隨着階層的增長,很是煩人寫一點點同樣的嘗試 - 除了塊以外。是否有可能爲整個班級創建某種「全局」例外? Python中推薦的處理方法是什麼?

+1

也許是裝飾者? – Milo

+0

您是否需要在每種方法中實際捕捉異常?你不能在你的類方法中捕獲它們,但在調用方法的代碼中捕獲它們。 –

回答

6

編寫一個或多個異常處理程序函數,給定函數及其中引發的異常,執行您想要執行的操作(例如顯示警報)。如果你需要不止一個,請寫下來。

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,雖然這是「魔術」,所以我沒有這樣做),所以它給你一些不太有用的信息。此外,上下文管理器不會讓您有機會返回處理程序中的任何內容。

+0

謝謝,我真的很喜歡contextmanager方法! – user2494129

3

我能想到的兩個選項:

  1. 寫一個裝飾,可以在try塊包裝每個方法。
  2. 編寫一個「調度程序」方法,調用try塊內的適當方法,然後調用該方法而不是單個方法。也就是說,不要致電obj.someMethod(),obj.otherMethod,請致電obj.dispatch('someMethod')obj.dispatch('otherMethod'),其中dispatch是包含try塊的包裝。

雖然你的方法看起來有點奇怪。在代碼的其他部分中提供對話框的東西可能更有意義,這是一些更高級別的事件循環,用於捕獲錯誤並顯示有關它們的消息。