python raise


原地址:http://openhome.cc/Gossip/Python/TryRaise.html


except後若不接上任何例外型態,則表示捕捉所有例外,這包括了所有的系統例外,有時這並不是你想要的行為。例如,下面這個程式,無法透過KeyboardInterrupt來中斷迴圈:

while True:
    try:
        print('Run it....')
    except:
         print('exception happened...')

由於except捕捉所有的例外,所以上例無法離開迴圈。你可以改為以下的方式:
while True:
    try:
        print('Run it....')
    except Exception:
         print('exception happened...')

在Python 3中,Exception是BaseException的子類別,可以捕捉除了系統例外以外的所有例外。上例可以藉由 KeyboardInterrupt中斷迴圈。

在Python 3中,可以在except捕捉到例外後,將例外物件指定給變數。例如:

>>> try:
...     raise IndexError('11')
... except IndexError as e:
...     print(type(e), str(e))
...
<class 'IndexError'> 11
>>>


在更進階的例外追蹤需求中,可以使用sys.exc_info()方法取得一個Tuple物件,該Tuple物件中包括了例外的類型、例外訊息以及traceback物件:
>>> try:
...     raise 'error'
... except:
...     a, b, c = sys.exc_info()
...     print(a)
...     print(b)
...     print(c)
...
<class 'TypeError'>
exceptions must derive from BaseException
<traceback object at 0x01D4FB20>
>>>


trackback物件代表了呼叫堆疊中每一個層次的追蹤,可以使用tb_next取得更深一層的呼叫堆疊。例如:
import sys
def test():
    raise EOFError

try:
    test()
except:
    type, message, traceback = sys.exc_info()
    while traceback:
        print('..........')
        print(type)
        print(message)
        print('function or module?', traceback.tb_frame.f_code.co_name)
        print('file?', traceback.tb_frame.f_code.co_filename)
        traceback = traceback.tb_next

tb_frame代表了
該層追蹤 的所有物件資訊,f_code可以取得該層的程式碼資訊,例如co_name可取得函式或模組名稱,而co_filename則表示該程式碼所在的檔案。上例的執行範例如下:
..........
<class 'EOFError'>

function or module? <module>
file? demo.py
..........
<class 'EOFError'>

function or module? test
file? demo.py

再來看看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',)
>>>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值