2013-02-22 188 views
0

爲了清晰起見,我正在編輯該問題。Python程序終止處理異常

我在導入MySQLdb的模塊中創建了一個類。我發現如果用戶傳遞給我的類的表不存在,MySQLdb將引發異常。我正在抓住這個例外,並將新的例外傳遞給客戶。但即使客戶端發現我的異常,程序仍然會終止。我也嘗試傳遞給客戶端相同的異常MySQLdb給我的課程。

由於客戶端將在一個循環中調用我的方法,傳入各種表名,所以我不希望程序在表名不好的情況下窒息。我希望客戶端的迭代繼續到下一個有效的表名。這裏是一個片段(表名是ARG通到法):

以我類/模塊:

 
    self.tableName = tableName 
    try:  
     self.cursor.execute("select * from " + self.tableName + ";") #Will raise Exception if the table does not exist. 
    except: 
     raise MyException("\n*** " + self.tableName + " does not exist. ***") 

在客戶端:

 
    tables = ["BadTableName", "GoodTableNameA", "GoodTableNameB","GoodTableNameC"] 

    try: 
     for table in tables: 
      my_method(table) #Exception message gets passed in with BadTableName, but the program ends. Subsequest iterations of this loop never happen 
    except Exception, e: 
     print e 

我想客戶端即使在調用my_method(BadTableName)之後仍然繼續。

順便說一句,my_method()是在客戶端導入的模塊中定義的類的一部分。

謝謝。

+0

MyException是否繼承自Exception或其他東西?你在哪個版本的Python上? – abarnert 2013-02-22 20:46:20

回答

0

在閱讀您編輯的問題後,我不確定您遇到的兩個問題中的哪一個。


如果您的問題只是你只想一個例外,只有終止一個循環迭代,而不是整個循環,它只是一個再嵌套在明顯的方式陳述問題。取而代之的是:

try: 
    for table in tables: 
     my_method(table) #Exception message gets passed in with BadTableName, but the program ends. Subsequest iterations of this loop never happen 
except Exception, e: 
    print e 

這樣做:

for table in tables: 
    try: 
     my_method(table) #Exception message gets passed in with BadTableName, but the program ends. Subsequest iterations of this loop never happen 
    except Exception, e: 
     print e 

在另一方面,如果問題是客戶不捕捉異常,這個問題很有可能是你的MyException不是Exception的子類。至少有三種方式可能發生。

由於您使用的舊式except語法(except Exception, e:),而不是新的樣式(except Exception as e:),你可能會使用舊版本的Python,讓你養不從BaseException繼承的類。例如:

class MyException(object): 
    def __init__(self, msg): 
     pass 

try: 
    raise MyException("dsfsdf") 
except Exception: 
    pass 

根據您的Python版本,這可能無法提高MyException,而是提出一個TypeError(' Out[11]: TypeError('exceptions must be old-style classes or derived from BaseException, not MyException')(將陷入),或打印一個警告,或者只是靜靜地「工作」,你問它(意思是你什麼也收不到,你的程序會以回溯的方式退出)。


同時,即使在2.7,仍然可以提高老式類,這也不會被抓到:

class MyException: 
    def __init__(self, msg): 
     pass 

try: 
    raise MyException("dsfsdf") 
except Exception: 
    pass 

這將永遠無法捕獲異常,和你的應用程序會以追蹤退出。


最後,如果你從BaseException而不是Exception繼承的,那麼顯然Exception不會趕上它。

class MyException(BaseException): 
    def __init__(self, msg): 
     pass 

try: 
    raise MyException("dsfsdf") 
except Exception: 
    pass 

再次,這將總是無法抓住你所提出的,並且你將以追蹤退出。

+0

謝謝你abarnert - 爲了答案,並花時間重新閱讀我編輯的問題。該解決方案是我提出的兩個建議原因中的第一個。以(現在非常)明顯的方式重新嵌套這些陳述有所幫助。再次感謝! – RLS 2013-02-22 21:08:44

+0

@RLS:是的,一旦你看到它,這就是顯而易見的事情,但也許之前並不明顯...... – abarnert 2013-02-23 01:17:08

0

1)不,引發異常並不總是導致程序終止。 未捕獲異常會導致程序終止。您可以使用try/except塊環繞代碼,如下所示,以阻止異常向上傳播堆棧。

try: 
    file = open("foo.txt") 
except IOError: 
    file = None 

2)實際捕獲異常的代碼可以訪問異常的源堆棧幀,並可以決定如何處理異常。

try: 
    some_function() 
except IOError as e: 
    raise 

新回溯重新引發錯誤(幾乎從未以作爲第一情況下很有用):

try: 
    some_function() 
except IOError as e: 
    raise e 

不要重新加註

再次加註原裝追蹤誤差並打印異常和回溯:

try: 
    some_function() 
except IOError as e: 
    import traceback 
    traceback.print_exc() 
+0

我很感謝你的回答。不幸的是,我的問題不是很清楚。爲了清晰起見,我編輯了它。請參閱編輯的問題。 – RLS 2013-02-22 20:46:11

1

異常並不總是導致程序結束。從docs:執行期間檢測到

錯誤被稱爲異常,並且不 無條件致命:

如果異常升高在try:除了塊和except子句指定異常或它將處理的異常的超類。

在處理異常時,您可以檢查它並找出與其相關的所有信息。我以前從未使用traceback模塊,但它看起來像包含您需要的所有內容。

我想你的第二個問題取決於你想讓你的用戶看到什麼。應該顯示例外嗎? (你有權訪問回溯)。應該只顯示消息?你應該記錄回溯?

1

添加到其他的答案:未捕獲的異常將終止程序,但只能在執行適用的finally block(如果有)和atexit handlers後執行。所以原則上,可以在未捕獲的異常之後無限期地繼續執行。

儘管如此,沒有一類異常只會打印錯誤消息並繼續執行。如果您需要,請使用warnings