2013年5月15日 星期三

Python: try...except

在python當中,例外處裡(Exception Handling)是用try...except敘述句來完成,不同於C++/Java當中的try...catch語句。但我有時會覺得疑惑except不是有"除此...之外"的意思嗎?!但這裡的except是當及物動詞使用,可以視為"丟出...的例外"的意思。(思維: 因為exception是例外,如果把它動詞化的話except就是"丟出...的例外"的意思)



Python


try:
     // Code here to try

except Exception:
      // Exception Handling



raise

再來看看raise的使用,正如在 try 陳述句 中看到的,你可以在raise後接上字串或例外類別名稱,現在已不鼓勵raise字串實例。實際上,raise之後可以接上例外類別名稱、例外實例或不接上任何東西。

當你在raise後接上例外類別時,實際上會以該類別建立實例再丟出,也就是下面兩行程式碼的作用是相同的:

raise EOFError
raise EOFError()

如果在except中使用raise而不接上任何物件,則表示將except比對到的例外實例再度丟出。例如:

>>> try:
...     raise EOFError
... except EOFError:
...     print('got it')
...     raise
...
got it
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
EOFError
>>>

如果必要的話,你還可以在except中raise例外時,附上except所比對到的例外實例。例如。
>>> try:
...     raise EOFError
... except EOFError as e:
...     print('got it')
...     raise IndexError from e
...
got it
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
EOFError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
IndexError
>>>


raise from語法,會將from後接上的例外實例,設定給被raise的例外實例之__cause__。例如:
>>> try:
...     try:
...         raise EOFError('XD')
...     except EOFError as e:
...         print(e.args)
...         raise IndexError('Orz') from e
... except IndexError as e:
...     print(e.args)
...     print(e.__cause__.args)
...
('XD',)
('Orz',)
('XD',)
>>>


實際上,如果你在except中raise某個例外,則原except所比對到的例外,無論有無使用raise from,都會自動設定給__context__。例如:
>>> try:
...     try:
...         raise EOFError('XD')
...     except EOFError as e:
...         print(e.args)
...         raise IndexError('Orz') from e
... except IndexError as e:
...     print(e.args)
...     print(e.__cause__.args)
...     print(e.__context__.args)
...

('XD',)
('Orz',)
('XD',)
('XD',)
>>>




Reference:
http://docs.python.org/2/tutorial/errors.html
http://caterpillar.onlyfun.net/Gossip/Python/TryRaise.html

沒有留言:

張貼留言