1. 程式人生 > 程式設計 >Python量化交易基礎講堂-try_except異常處理機制

Python量化交易基礎講堂-try_except異常處理機制

《Python實戰-構建基於股票的量化交易系統》小冊子主要側重於 Python 實戰講解,但在內容設計上提供了前置基礎章節幫助讀者快速掌握基礎工具的使用。同時我們會持續更新一些關於Python和量化相關擴充套件文章,幫助大家夯實基礎和增值學習效果。目前已經推出如下文章:

本次專欄篇我們來介紹Python中的try_except異常處理機制。

在Python程式設計中不可避免的會出現錯誤,在除錯階段出現語法之類的錯誤時,Pycharm會在Debug視窗提示錯誤,但是程式在執行時由於內部隱含的問題而引起錯誤,會導致程式終止執行。比如以下例程中,使用urllib庫開啟URL時由於網路問題而發生了錯誤:

import urllib.request
req = urllib.request.urlopen('http://www.baidu.com')
print(req.read())
Traceback (most recent call last):
……
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time,or established connection failed because connected host has failed to respond
複製程式碼

在Python中出現直譯器無法正常處理的程式時會引發異常。如果要避免程式在異常發生時結束執行,那麼通常使用異常處理語句捕捉異常,再通過其他的邏輯程式碼讓程式繼續執行。異常處理語句為try/except,它的基本語法結構如下:

try:
    < 語句 >  # 執行程式碼
except  [(Error1,Error2,...)[as e]]:
    < 語句 >  # 如果在try中引發了'Error1'異常
except  [(Error3,Error4,...)[as e]]:
    < 語句 >  # 如果在try中引發了'Error3'異常
except:
    < 語句 >  # 如果在try中引發了其他異常
複製程式碼

當Python直譯器在執行 try 中的程式碼時出現異常,Python 直譯器會依次判斷該異常物件是否是 except 塊後的異常類或其子類的例項,根據該異常的型別尋找能處理該異常物件的 except 塊,如果找到合適的 except 塊,則把該異常物件交給該 except 塊處理。如果 Python 直譯器找不到捕獲異常的 except 塊,則程式執行終止,Python 直譯器也將退出。

從 try except 的基本語法格式可以看出,try 塊僅有一個,但 except 程式碼塊可以有多個,這是為了針對不同的異常型別提供不同的異常處理方式,比如以下例程中,分別定義了浮點計算錯誤FloatingPointError異常和輸入/輸出操作失敗IOError異常:

try:
    import urllib.request
    req = urllib.request.urlopen('http://www.baidu.com')
    print(req.read())
except FloatingPointError:
    print("Capture FloatingPointError")
except IOError:
    print("Capture IOError")
except Exception:
    print("Capture Error")
except:
    print("Capture Error")

複製程式碼

以上程式針對 FloatingPointError、IOError型別的異常,提供了專門的異常處理邏輯。該程式執行時的異常處理邏輯可能有如下幾種情形:

  • 如果在執行該程式時出現浮點計算錯誤,Python 將呼叫 FloatingPointError 對應的 except 塊處理該異常。
  • 如果在執行該程式時出現輸入/輸出操作失敗,Python 將呼叫IOError對應的 except 塊處理該異常。此處直譯器會執行IOError的異常處理。
  • 如果在程式執行時出現其他異常,Python 可以呼叫 Exception 對應的 except 塊處理該異常。當然except後面也可以不指定任何異常類。

在語法中的[]內為可選內容,於是可以有以下幾種形式:

  • except 後不指定具體的異常名稱,表示要捕獲所有型別的異常。
try:
    < 語句 >  # 執行程式碼
except:
    < 語句 >  # 如果在try中引發了其他異常
複製程式碼
  • except 後指定具體的異常名稱,表示捕獲指定型別的異常。比如 Error1、Error2、Error3、Error4分別表示各自的 except 塊可以處理異常的具體型別。
try:
    <語句>    # 執行程式碼
except  Error1:
    <語句>    # 如果在try中引發了'Error1'異常
try:
    < 語句 >  # 執行程式碼
except (Error2,Error3):
    < 語句 >  # 如果在try中引發了'Error2和Error3'異常 
複製程式碼
  • [as e] 表示將異常型別賦值給變數 e,以便於在 except 塊中呼叫異常型別。所有的異常物件都包含了如下幾個常用屬性和方法:

    args:該屬性返回異常的錯誤編號和描述字串。

    errno:該屬性返回異常的錯誤編號。

    strerror:該屬性返回異常的描述字串。

    with_traceback():通過該方法可處理異常的傳播軌跡資訊。

try:
    import urllib.request
    req = urllib.request.urlopen('http://www.baidu.com')
    print(req.read())
except FloatingPointError:
    print("Capture FloatingPointError")
except IOError as e:
    print("Capture IOError")
    print(e.args) # 訪問異常的錯誤編號和詳細資訊
    print(e.errno) # 訪問異常的錯誤編號
    print(e.strerror) # 訪問異常的詳細資訊
except:
    print("Capture Error")
(TimeoutError(10060,'A connection attempt failed because the connected party did not properly respond after a period of time,or established connection failed because connected host has failed to respond',None,10060,None),)
None
None 
複製程式碼

如果要檢視更詳細的異常資訊,可以匯入traceback模組,使用print_exc()列印異常資訊。print_exc()還可以接受file引數直接寫入到一個檔案。比如:

traceback.print_exc(file=open('except.txt','w+')) # 寫入到except.txt檔案去
複製程式碼

關於完整程式碼可以加入小冊子交流群獲取。更多的量化交易內容歡迎大家訂閱小冊子閱讀