python3(三十二) try except


""" 異常處理 """
__author__on__ = 'shaozhiqi  2019/9/19'

# 大量的代碼來判斷是否出錯:
# def foo():
#     r = some_function()
#     if r == (-1):
#         return (-1)
#     # do something
#     return r
#
#
# def bar():
#     r = foo()
#     if r == (-1):
#         print('Error')
#     else:
#         pass
# 用異常機制來處理
try:
    print('try...')
    r = 10 / 0
    print('result:', r)
except ZeroDivisionError as e:
    print('except:', e)  # 執行結果: except: division by zero
finally:
    print('finally...')
print('END')
# 我們認為某些代碼可能會出錯時,就可以用try來運行這段代碼,
# 如果執行出錯,則后續代碼不會繼續執行,而是直接跳轉至錯誤處理代碼,
# 即except語句塊,執行完except后,如果有finally語句塊,則執行finally語句塊,至此,執行完畢。

# -----------------------------------------------------------------------------
# 如果沒有錯誤發生,可以在except語句塊后面加一個else,當沒有錯誤發生時,會自動執行else語句:
try:
    print('try...')
    r = 10 / int('2')
    print('result:', r)
except ValueError as e:
    print('ValueError:', e)
except ZeroDivisionError as e:
    print('ZeroDivisionError:', e)
else:
    print('no error!')
finally:
    print('finally...')
print('END')


# 執行結果:
# try...
# result: 5.0
# no error!
# finally...
# END
# 異常列表:https://docs.python.org/3/library/exceptions.html#exception-hierarchy

# ----------------------------------------------------------------
# 只要在最上層捕獲了,就可以處理
def foo(s):
    return 10 / int(s)


def bar(s):
    return foo(s) * 2


def main():
    try:
        bar('0')
    except Exception as e:
        print('Error:', e)
    finally:
        print('finally...')


main()
# 執行結果:
# Error: division by zero
# finally...
# 不需要在每個可能出錯的地方去捕獲錯誤,只要在合適的層次去捕獲錯誤就可以了

# -------------------------------------------------------------------------
# 如果不捕獲錯誤,自然可以讓Python解釋器來打印出錯誤堆棧,但程序也被結束了。
# 既然我們能捕獲錯誤,就可以把錯誤堆棧打印出來,然后分析錯誤原因,同時,讓程序繼續執行下去。
import logging


def foo(s):
    return 10 / int(s)


def bar(s):
    return foo(s) * 2


def main():
    try:
        bar('0')
    except Exception as e:
        logging.exception(e)


main()
print('END')


# ---------------------------------------------------------------------
# 自定義異常,並拋出自定義異常,不捕獲的話程序中斷
class FooError(ValueError):
    pass


def foo(s):
    n = int(s)
    if n == 0:
        raise FooError('invalid value: %s' % s)
    return 10 / n


# foo('0')  # __main__.FooError: invalid value: 0


# 拋出系統異常
def foo(s):
    n = int(s)
    if n == 0:
        raise ValueError('invalid value: %s' % s)
    return 10 / n


def bar():
    try:
        foo('0')
    except ValueError as e:
        print('ValueError!')
        raise


bar()  # ValueError: invalid value: 0
# 捕獲錯誤目的只是記錄一下,便於后續追蹤。
# 由於當前函數不知道應該怎么處理該錯誤,所以,最恰當的方式是繼續往上拋,讓頂層調用者去處理。
# raise語句如果不帶參數,就會把當前錯誤原樣拋出。此外,在except中raise一個Error,還可以把一種類型的錯誤轉化成另一種類型:
try:
    10 / 0
except ZeroDivisionError:
    raise ValueError('input error!')
# 切勿在業務中如上處理,這樣就不知道到底是啥異常了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM