在寫Python程序的時候常常會報錯,報錯一般有如下兩種狀況:python
語法錯誤也稱爲解析錯誤,是最常遇到的一種錯誤程序員
In [1]: while True print('Hello!') File "<ipython-input-1-5c66e4fd0ae9>", line 1 while True print('Hello!') ^ SyntaxError: invalid syntax
當代碼不符合Python語法的時候就會拋出SyntaxError。網絡
Python用異常對象來表示異常狀況。遇到錯誤後,會引起異常。若是異常沒有處理或捕捉,程序就會用traceback終止程序的執行,若是是在多線程程序中,則會終止當前線程的執行。多線程
In [2]: 1/0 --------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-2-05c9758a9c21> in <module>() ----> 1 1/0 ZeroDivisionError: division by zero
除以0時,就會拋出ZeroDivisionError異常(ZeroDivisionError類的一個實例)。異步
Python 3.5.2中內置異常的類層次結構以下:參考標準庫ide
BaseException # 全部異常的基類 +-- SystemExit # 程序退出/終止 +-- KeyboardInterrupt # 由鍵盤中斷(一般爲Ctrl+C) 生成 +-- GeneratorExit # 由生成器.close()方法引起 +-- Exception # 全部非退出異常的基類 +-- StopIteration # 中止迭代錯誤 +-- StopAsyncIteration # 中止異步迭代錯誤 +-- ArithmeticError # 算數異常的基類 | +-- FloatingPointError # 浮點操做異常 | +-- OverflowError # 溢出致使的異常 | +-- ZeroDivisionError # 對0進行除或取模操做致使的異常 +-- AssertionError # 由assert語句引起 +-- AttributeError # 當屬性名稱無效時引起 +-- BufferError # 緩衝區錯誤引起 +-- EOFError # 到達文件結尾時引起 +-- ImportError # import語句失敗 +-- LookupError # 索引和鍵錯誤 | +-- IndexError # 超出序列索引的範圍 | +-- KeyError # 鍵不存在 +-- MemoryError # 內存不足 +-- NameError # 沒法找到局部或全局名稱 | +-- UnboundLocalError # 未綁定的局部變量 +-- OSError # 操做系統錯誤 | +-- BlockingIOError # IO阻塞 | +-- ChildProcessError # 子進程 | +-- ConnectionError # 鏈接錯誤 | | +-- BrokenPipeError # 管道斷開 | | +-- ConnectionAbortedError # 鏈接停止 | | +-- ConnectionRefusedError # 鏈接拒絕 | | +-- ConnectionResetError # 鏈接重置 | +-- FileExistsError # 文件已存在 | +-- FileNotFoundError # 文件不存在 | +-- InterruptedError # 中斷錯誤 | +-- IsADirectoryError # 目錄錯誤 | +-- NotADirectoryError # 非目錄錯誤 | +-- PermissionError # 權限錯誤 | +-- ProcessLookupError # 進程查找錯誤 | +-- TimeoutError # 超時錯誤 +-- ReferenceError # 銷燬被引用對象後仍然使用引用 +-- RuntimeError # 運行時錯誤 | +-- NotImplementedError # 沒有實現的特性 | +-- RecursionError # 遞歸錯誤 +-- SyntaxError # 語法錯誤 | +-- IndentationError # 縮進錯誤 | +-- TabError # 使用不一致的製表符 +-- SystemError # 解釋器中的非致命系統錯誤 +-- TypeError # 給操做傳遞了錯誤的類型 +-- ValueError # 無效類型 | +-- UnicodeError # Unicode錯誤 | +-- UnicodeDecodeError # Unicode解碼錯誤 | +-- UnicodeEncodeError # Unicode編碼錯誤 | +-- UnicodeTranslateError # Unicode轉換錯誤 +-- Warning # 警告的基類 +-- DeprecationWarning # 關於被棄用的特徵的警告 +-- PendingDeprecationWarning # 關於特性將會被廢棄的警告 +-- RuntimeWarning # 可疑的運行時行爲的警告 +-- SyntaxWarning # 可疑的語法的警告 +-- UserWarning # 用戶代碼生成的警告 +-- FutureWarning # 關於構造未來語義會有改變的警告 +-- ImportWarning # import語句的警告 +-- UnicodeWarning # Unicode警告 +-- BytesWarning # Bytes警告 +-- ResourceWarning # 資源警告
捕獲異常可使用try/except語句。try/except語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常信息並處理。函數
基礎語法學習
try: <語句> except <name>: <語句> #若是在try部分引起了名爲'name'的異常,則執行這段代碼
示例ui
In [3]: try: ...: x = int(input("Please enter a number: ")) ...: except ValueError: ...: print("No valid number.") ...: Please enter a number: asd No valid number.
In [4]: import sys In [5]: try: ...: f = open('file.txt') # 文件不存在的時候就會拋出FileNotFoundError異常 ...: s = f.readline() ...: i = int(s.strip()) ...: except OSError: # FileNotFoundError異常的上層異常 ...: print('OS error.') ...: except ValueError: ...: print('Could not convert data to integer.') ...: except Exception: ...: print('Exception.') ...: except: # 不加具體異常類型時,會捕獲全部的異常,應該不用或者慎用 ...: print('Unexpected error:', sys.exc_info()[0]) ...: OS error.
各個except之間的執行順序:編碼
語法
try: <語句> except <name>: <語句> #若是在try部分引起了名爲'name'的異常,則執行這段代碼 else: <語句> #若是沒有異常發生,則執行這段代碼
若是try部分沒有拋出異常,可是又必須執行的語句,則放在else語句中。
代碼
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print('cannot open', arg) else: # 沒有拋出異常(即文件正確打開)時打印出文件中的每一行 print(arg, 'has', len(f.readlines()), 'lines') f.close()
finally語句用來定義在任何狀況下都必須執行的語句。
In [1]: try: ...: raise KeyboardInterrupt ...: finally: ...: print('Goodbye') ...: Goodbye --------------------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) <ipython-input-8-132d568ca0fb> in <module>() 1 try: ----> 2 raise KeyboardInterrupt 3 finally: 4 print('Goodbye') 5 KeyboardInterrupt:
帶return語句的finally執行順序
def p(x): print(x) return x def t(): try: return p(2) print('haha') finally: return p(3) x = t() # 輸出結果爲: 2 3 # 返回值x爲3
可見,在try塊中,只要有finally語句,即便函數提早返回,也會在退出try塊以前執行finally語句,所以返回值會被finally中的return語句替代。
綜合使用示例
In [1]: def divide(x, y): ...: try: ...: result = x / y ...: except ZeroDivisionError: ...: print('division by zero!') ...: else: ...: print('result is ', result) ...: finally: ...: print('executing finally clause.') ...: In [2]: divide(2, 0) division by zero! executing finally clause. In [3]: divide(2, 1) result is 2.0 executing finally clause. In [4]: divide('2', '1') executing finally clause. --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-4-34bb38fa74fd> in <module>() ----> 1 divide('2', '1') <ipython-input-1-4273ffa41b76> in divide(x, y) 1 def divide(x, y): 2 try: ----> 3 result = x / y 4 except ZeroDivisionError: 5 print('division by zero!') TypeError: unsupported operand type(s) for /: 'str' and 'str'
結論:
raise語句
In [1]: raise NameError('Hello') --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-1-64f372e60821> in <module>() ----> 1 raise NameError('Hello') NameError: Hello
用戶自定義異常類時,應該直接或者間接的繼承自Exception類。
class CustomException(Exception): def __init__(self, code, message): self.code = code self.message = message try: raise CustomException(500, 'error') except CustomException as e: print('{},{}'.format(e.code, e.message)) # 輸出結果:500,error
在函數內引起異常時,若是異常沒有被捕獲到,那麼它就會被傳播到函數被調用的地方。
In [1]: def a(): ...: raise Exception('Hello') ...: In [2]: def b(): ...: print('enter b') ...: a() # 函數a中引起的異常,會傳遞到父函數的調用出 ...: print('exit b') # a中拋出異常以後傳遞到b,停止b的執行 ...: In [3]: b() enter b --------------------------------------------------------------------------- Exception Traceback (most recent call last) <ipython-input-3-9c619ddbd09b> in <module>() ----> 1 b() <ipython-input-2-f99a565bd6f8> in b() 1 def b(): 2 print('enter b') ----> 3 a() 4 print('exit b') 5 <ipython-input-1-6e68e60e93b5> in a() 1 def a(): ----> 2 raise Exception('Hello') Exception: Hello
記得幫我點贊哦!
精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你須要的學習資料,還在等什麼?快去關注下載吧!!!
念念不忘,必有迴響,小夥伴們幫我點個贊吧,很是感謝。
我是職場亮哥,YY高級軟件工程師、四年工做經驗,拒絕鹹魚爭當龍頭的斜槓程序員。
聽我說,進步多,程序人生一把梭
若是有幸能幫到你,請幫我點個【贊】,給個關注,若是能順帶評論給個鼓勵,將不勝感激。
職場亮哥文章列表:更多文章
本人全部文章、回答都與版權保護平臺有合做,著做權歸職場亮哥全部,未經受權,轉載必究!