python 期货交易_Python期货量化交易基础教程(8)
8、錯(cuò)誤和異常處理
Python中常見的錯(cuò)誤有兩類,一是語法錯(cuò)誤,二是異常。
語法錯(cuò)誤是違反了Python語法規(guī)則,導(dǎo)致代碼無法執(zhí)行。
異常是語法沒有錯(cuò)誤,但在執(zhí)行過程中因?yàn)榇a邏輯問題又發(fā)生了故障。
8.1、try語句:
Python中用try語句處理異常。
我們先從示例開始:
>>> if:
File "", line 1
if:
^
SyntaxError: invalid syntax
>>>
此例是一個(gè)不完整的if語句,報(bào)了語法錯(cuò)誤:SyntaxError,具體內(nèi)容為invalid syntax,語法錯(cuò)誤在編寫代碼時(shí)就應(yīng)當(dāng)避免。
再看下一個(gè)例子:
>>> def func(a):
... print(a+5)
...
>>> a='xyz'
>>> func(a)
Traceback (most recent call last):
File "", line 1, in
File "", line 2, in func
TypeError: can only concatenate str (not "int") to str
>>> func(b)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'b' is not defined
>>>
此例定義一個(gè)函數(shù)func和一個(gè)變量a,然后調(diào)用func并把a(bǔ)作為參數(shù)傳入,語法沒有錯(cuò)誤,但a是字符串不能與整型相加,產(chǎn)生了邏輯錯(cuò)誤,所以拋出了異常類型錯(cuò)誤:TypeError,具體內(nèi)容為can only concatenate str(not"int") to str。調(diào)用func(b)由于b沒有定義,所以拋出了異常名字錯(cuò)誤:NameError,具體內(nèi)容為name 'b'is not defined
我們先用一簡(jiǎn)單的try語句捕捉上例異常,因?yàn)槲覀円呀?jīng)知道了異常是類型錯(cuò)誤和名字錯(cuò)誤,所以可如下寫:
>>> try :
... func(a)
... func(b)
... except TypeError:
... print('a值不能運(yùn)算')
... except NameError:
... print('b未定義')
...
a值不能運(yùn)算
>>>
try后跟可能拋出異常的語句func(a)、func(b),except后跟異常名,表示捕捉指定異常,try按字面意思就是嘗試運(yùn)行其后的語句,如果發(fā)生異常就由后面的except捕捉。此例有兩個(gè)異常,所以用兩個(gè)except捕捉,指定的異常是TypeError和NameError,捕捉到了異常則執(zhí)行該異常下的語句塊,輸出結(jié)果只有'a值不能運(yùn)算',說明當(dāng)捕捉到一個(gè)異常后,其余的異常不再捕捉,因?yàn)槠溆嗫赡墚a(chǎn)生異常的語句沒有再執(zhí)行的意義。
如果多個(gè)異常會(huì)用到同樣的處理語句,則多個(gè)異常可以放在同一個(gè)except后面,例如:
>>> try :
... func(a)
... func(b)
... except (TypeError,NameError):
... print('a值不能運(yùn)算或b值未定義')
...
a值不能運(yùn)算或b值未定義
>>>
表示捕捉異常TypeError或NameError。
我們可以用as語句獲取異常的具體內(nèi)容,并將內(nèi)容賦值給變量,如下:
>>> try :
... func(a)
... except TypeError as T:
... print('a值不能運(yùn)算')
... print(T)
...
a值不能運(yùn)算
can only concatenate str (not "int") to str
>>>
用as語句把TypeError的具體內(nèi)容賦值給T,再輸出T,即:can only concatenate str(not"int") to str
如果except后跟Exception,則捕捉所有的常規(guī)異常錯(cuò)誤,例如:
>>> try :
... func(a)
... except Exception as e:
... print('捕捉到了異常:',e)
...
捕捉到了異常: can only concatenate str (not "int") to str
>>>
如果except后不跟異常名,則捕捉所有的異常,包括自定義的異常,例如:
>>> try :
... func(a)
... except :
... print('捕捉到了異常')
...
捕捉到了異常
>>>
但不建議這么做,因?yàn)椴恢喇惓5木唧w內(nèi)容是什么,難以對(duì)異常排查,所以except后至少應(yīng)跟常規(guī)異常Exception,自定義的異常也應(yīng)該繼承Exception。
我們可用mro()函數(shù)查看異常的繼承順序,例如:
>>> TypeError.mro()
[, , , ]
>>>
從繼承的順序可知,異常的太上皇是BaseException,BaseException是所有異常的基類,BaseException一般用不到,常規(guī)錯(cuò)誤基類Exception是皇上,用到Exception就夠了,自定義的異常也應(yīng)直接或間接繼承Exception。通常對(duì)于不確定的異常用Exception捕捉,并放在最后捕捉,如果放前面則異常都被Exception截獲,其后的異常不會(huì)再被檢驗(yàn)。
更全異常捕捉示例:
>>> try :
... func(a)
... func(b)
... except TypeError as T:
... print('a值不能運(yùn)算')
... print(T)
... except NameError as N:
... print('b值未定義')
... print(N)
... except Exception as e:
... print(e)
...
a值不能運(yùn)算
can only concatenate str (not "int") to str
>>>
如果執(zhí)行語句沒有異常,try語句便可以執(zhí)行結(jié)束了,但若需要在沒有異常時(shí)也執(zhí)行某些語句,可以用else語句執(zhí)行,例如:
>>> a=4;b=6
>>> try :
... func(a)
... func(b)
... except TypeError as T:
... print('a值不能運(yùn)算')
... print(T)
... except NameError as N:
... print('b值未定義')
... print(N)
... except Exception as e:
... print(e)
... else:
... print('沒有異常')
...
9
11
沒有異常
>>>
重新定義了a、b兩個(gè)整數(shù),則調(diào)用func(a)、func(b)便可正常執(zhí)行,沒有捕捉到異常則執(zhí)行else語句。
最后,如果不管是否有異常,都要執(zhí)行某些操作,比如釋放資源,則用finally語句來執(zhí)行,例如:
>>> try :
... func(a)
... func(b)
... except TypeError as T:
... print('a值不能運(yùn)算')
... print(T)
... except NameError as N:
... print('b值未定義')
... print(N)
... except Exception as e:
... print(e)
... else:
... print('沒有異常')
... finally:
... print('刪除變量釋放資源')
... del a,b
...
9
11
沒有異常
刪除變量釋放資源
>>> a
Traceback (most recent call last):
File "", line 1, in
NameError: name 'a' is not defined
>>> b
Traceback (most recent call last):
File "", line 1, in
NameError: name 'b' is not defined
>>>
finally語句里刪除了變量a、b,所以再調(diào)用a、b時(shí)報(bào)了NameError。以上便是try異常處理語句的基本結(jié)構(gòu)。
8.2、raise語句:
我們除了讓程序運(yùn)行時(shí)自動(dòng)拋出異常外,還可以按需要主動(dòng)拋出異常,Python中用raise語句拋出指定的異常,并可向異常傳遞數(shù)據(jù)。
我們先看一個(gè)示例:
def func(a):
if type(a) != int:
raise ValueError
print(a+5)
函數(shù)中用if語句判斷參數(shù)a,不是整型時(shí)拋出ValueError異常,執(zhí)行效果如下:
>>> a='xyz'
>>> func(a)
Traceback (most recent call last):
File "", line 1, in
File "", line 3, in func
ValueError
>>> try:
... func(a)
... except ValueError as e:
... print(e,'不是整型')
...
不是整型
前面我們把字符串傳入func由程序拋出異常時(shí)拋出的是TypeError,這次我們用raise主動(dòng)拋出異常,則拋出了指定異常ValueError 。
ValueError并沒有具體信息,所以print語句沒有輸出e的值,我們可以用raise拋出異常的同時(shí)傳入數(shù)據(jù),例如:
>>> def func(a):
... if type(a) != int:
... raise ValueError('不是整型')
... print(a+5)
...
>>> a='xyz'
>>> try:
... func(a)
... except ValueError as e:
... print(e)
...
不是整型
>>>
這次拋出的ValueError異常輸出了具體信息“不是整型”。
8.3、自定義異常類:
我們可自己定義異常類,自定義異常應(yīng)繼承常規(guī)異常類Exception,例如:
class ZiError(Exception):
def __init__(self, arg):
self.arg = arg
def __str__(self):
return self.arg
自定義異常需要用raise語句主動(dòng)拋出,且會(huì)自動(dòng)調(diào)用__str__()函數(shù)返回異常具體信息,例如:
>>> def func(a):
... if type(a) != int:
... raise ZiError('不是整型') #拋出ZiError的實(shí)例,arg值為'不是整型'
... print(a+5)
...
>>> a='xyz';b=5
>>> try:
... func(b)
... func(a)
... except ZiError as z:
... print(z)
...
10
不是整型
>>>
func(b)可正常執(zhí)行,但func(a)拋出自定義異常ZiError,并輸出異常信息:不是整型。
總結(jié)
以上是生活随笔為你收集整理的python 期货交易_Python期货量化交易基础教程(8)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python locale模块_使用py
- 下一篇: java显式构造函数_C++中的显式构造