2016-10-08 43 views
2

在Python 3中,有一個useful raise ... from ... feature來重新引發異常。也就是說,你如何從引發異常中找到原始(/重新提出的)異常?這裏有一個(傻),例如有意見來證明什麼,我mean--如何訪問Python 3中重新產生的異常?

def some_func(): 
    try: 
     None() # TypeError: 'NoneType' object is not callable 
    except as err: 
     raise Exception("blah") from err 

try: 
    some_func() 
except as err: 
    # how can I access the original exception (TypeError)? 
+0

順便說一句:使用'from'主要用於從'None'引發異常(「blah」),它告訴python *隱藏* TypeError並使其不可訪問。 *默認情況下,TypeError已經存儲在新的異常中(這就是爲什麼你會在回溯過程中處理上述異常等待消息的時候),所以'raise ... from err'幾乎是沒有用的。 – Bakuriu

回答

3

它在引發異常的__cause__屬性。從docs on the raise statement採取它說關於raise ... from ...

from子句是用於異常鏈:如果給定的,所述第二表達式必須是另一個異常類或實例,然後將被連接到升高的異常爲__cause__屬性(可寫)。如果未處理引發的異常,則會打印這兩個異常。

因此,在您指定的方案,repr荷蘭國際集團的__cause__屬性:

def some_func(): 
    try: 
     None() # TypeError: 'NoneType' object is not callable 
    except TypeError as err: 
     raise Exception("blah") from err 

try: 
    some_func() 
except Exception as er: 
    print(repr(er.__cause__)) 

會打印出:

TypeError("'NoneType' object is not callable",) 
1

每當異常是從異常處理程序提出(在except條款),最初的例外將在新的例外__context__中得到推薦。

每當使用from語法引發異常時,將在from中指定的異常保存在新異常的__cause__屬性中。

在通常使用情況下,相當於兩個__cause____context__含有原始異常:

def f(): 
    try: 
     raise Exception('first exception') 
    except Exception as e: 
     raise Exception('second exception') from e 

try: 
    f() 
except Exception as e: 
    print('This exception', e) 
    print('Original exception', e.__context__) 
    print('Also original exception', e.__cause__) 

這裏也是當__context__被設定的一個例子:

try: 
    raise Exception('first exception') 
except Exception as e: 
    raise Exception('second exception') 

和示例當設置爲__cause__時:

e = Exception('first exception') 
raise Exception('second exception') from e 
+0

啊,整齊。不知道關於'__context__'。 –