Python 断言和异常
Python 斷言和異常
Python斷言
斷言是一種理智檢查,當(dāng)程序的測試完成,可以將其打開或關(guān)閉。斷言的最簡單方法就是把它比作raise-if語句(或更加準(zhǔn)確,raise-if-not聲明)。一個表達(dá)式進(jìn)行測試,如果結(jié)果出現(xiàn)false,將引發(fā)異常。程序中常常放置斷言來檢查輸入的有效與否,或在一個函數(shù)調(diào)用后檢查有效的輸出,其為assert關(guān)鍵字構(gòu)成的語句。
assert語句
但它遇到一個斷言語句,Python評估計算之后的表達(dá)式,希望是true。如果是表達(dá)式為false,Python觸發(fā)AssertionError異常,其語法是:
assert Expression[, Arguments]
如果斷言失敗,Python使用ArgumentExpression作為AssetionError異常的參數(shù),AssertionError可以被捕獲,并用try-except語句處理,類似其他異常。但是如果沒有處理它們,將終止改成程序并產(chǎn)生一個回溯。如下實例:
def kelvin_to_fahrenheit(temperature):
assert temperature >= 0, "Colder than absolute zero!"
return ((temperature-273)*1.8)+32
print(kelvin_to_fahrenheit(273))
print(kelvin_to_fahrenheit(505.78))
print(kelvin_to_fahrenheit(-5))
運(yùn)行輸出結(jié)果為:
32.0
451.00399999999996
Traceback (most recent call last):
File "D:/PythonCode/basic knowledge/exceptions.py", line 8, in <module>
print(kelvin_to_fahrenheit(-5))
File "D:/PythonCode/basic knowledge/exceptions.py", line 2, in kelvin_to_fahrenheit
assert temperature >= 0, "Colder than absolute zero!"
AssertionError: Colder than absolute zero!
Python 異常處理
Python提供的標(biāo)準(zhǔn)異常如下列表:
| 異常名稱 | 描述 |
|---|---|
| Exception | 所有異常的基類 |
| StopIteration | 當(dāng)一個迭代器的next()方法不能指向任何對象時引發(fā) |
| SystemExit | 由sys.exit()函數(shù)引發(fā) |
| StandardError | 除了StopIteration異常和SystemExit,所有內(nèi)置異常的基類 |
| ArithmeticError | 數(shù)值計算所發(fā)生的所有異常的基類 |
| OverflowError | 當(dāng)數(shù)字類型計算超過最高限額引發(fā) |
| FloatingPointError | 當(dāng)一個浮點(diǎn)運(yùn)算失敗時觸發(fā) |
| ZeroDivisonError | 當(dāng)除運(yùn)算或模零在所有數(shù)值類型運(yùn)算時引發(fā) |
| AssertionError | 斷言語句失敗的情況下引發(fā) |
| AttributeError | 屬性引用或賦值失敗的情況下引發(fā) |
| EOFError | 當(dāng)從 raw_input() 與 input() 函數(shù)輸入,到達(dá)文件末尾時觸發(fā) |
| ImportError | 當(dāng)一個 import 語句失敗時觸發(fā) |
| KeyboardInterrupt | 當(dāng)用戶中斷程序執(zhí)行,通常是通過按 Ctrl+c 引發(fā) |
| LookupError | 所有查找錯誤基類 |
| IndexError、KeyError | 當(dāng)在一個序列中沒有找到一個索引時引發(fā);當(dāng)指定的鍵沒有在字典中找到引發(fā) |
| NameError | 當(dāng)在局部或全局命名空間中找不到的標(biāo)識引發(fā) |
| UnboundLocalError | 試圖訪問在函數(shù)或方法的局部變量時引發(fā),但沒有值分配給它 |
| EnvironmentError | Python環(huán)境之外發(fā)生的所有異常的基類。 |
| IOError | 當(dāng)一個輸入/輸出操作失敗,如打印語句或 open()函數(shù)試圖打開不存在的文件時引發(fā);操作系統(tǒng)相關(guān)的錯誤時引發(fā) |
| SyntaxError、IndentationError | 當(dāng)在Python語法錯誤引發(fā);沒有正確指定縮進(jìn)引發(fā) |
| SystemError、SystemExit | 當(dāng)解釋器發(fā)現(xiàn)一個內(nèi)部問題,但遇到此錯誤時,Python解釋器不退出引發(fā);當(dāng)Python解釋器不使用sys.exit()函數(shù)引發(fā)。如果代碼沒有被處理,解釋器會退出 |
| ValueError | 在內(nèi)置函數(shù)對于數(shù)據(jù)類型,參數(shù)的有效類型時引發(fā),但是參數(shù)指定了無效值 |
| RuntimeError | 當(dāng)生成的錯誤不屬于任何類別時引發(fā) |
| NotImplementedError | 當(dāng)要在繼承的類來實現(xiàn),抽象方法實際上沒有實現(xiàn)時引發(fā)此異常 |
什么是異常
異常是一個事件,在程序的執(zhí)行過程中擾亂程序的正常流程。一般來說,當(dāng)Python程序遇到某種情況,它無法應(yīng)付則會引發(fā)一個異常。
異常處理
我們可以使用try/except語句來捕捉異常,try/except語句用來檢測try語句塊中的異常,從而讓except語句捕獲異常信息并處理。如果我們不想在異常發(fā)生時程序結(jié)束,只需要在except里捕獲它,其語法格式如下:
try:
<statement>
except <name>:
<statement>
except <name>, <data>:
<statement>
else:
<statement>
try的工作原理,當(dāng)開始一個try語句后,Python就在當(dāng)前程序的上下文中做標(biāo)記,這樣當(dāng)異常出現(xiàn)時,就可以回到這里,try子句先執(zhí)行,接下來會發(fā)生什么依賴于執(zhí)行時是否出現(xiàn)異常。
如果try后的語句執(zhí)行時發(fā)生異常,Python就跳回到try并執(zhí)行第一個匹配該異常的except子句,異常處理完畢,控制流就通過整個try語句(除非在處理異常時又引發(fā)新的異常);
如果try后的語句里發(fā)生了異常,卻沒有匹配的except子句,異常將被遞交到上層的try,或者到程序的最上層(這樣將結(jié)束程序,并打印缺省的出錯信息);
如果try子句執(zhí)行時沒有發(fā)生異常,Python將執(zhí)行else語句后的語句(如果有else的話),然后控制流通過整個try語句;
以下實例,打開文件,在該文件中寫入內(nèi)容,并未發(fā)生異常:
try:
fh = open("testfile.txt", "w", encoding="utf-8")
fh.write("這是一個測試文件,用于測試異常!")
except IOError:
print("Error:沒有找到文件或讀取文件失敗!")
else:
print("內(nèi)容寫入文件成功!")
fh.close()
運(yùn)行輸出結(jié)果為:
內(nèi)容寫入文件成功!
# 查看文件內(nèi)容
這是一個測試文件,用于測試異常!
以下實例,打開文件,在該文件中寫入內(nèi)容,但文件沒有寫入權(quán)限,發(fā)生了異常(Linux環(huán)境下):
try:
fh = open("testfile", "w")
fh.write("這是一個測試文件,用于測試異常!!")
except IOError:
print("Error: 沒有找到文件或讀取文件失敗")
else:
print("內(nèi)容寫入文件成功")
fh.close()
在執(zhí)行代碼前為了測試方便,我們可以先去掉testfile.txt文件的寫權(quán)限,命令如下:
chmod -w testfile.txt
在運(yùn)行上面代碼輸出結(jié)果為:
Error: 沒有找到文件或讀取文件失敗
使用except而不帶任何異常類型
我們可以不帶任何異常類型使用except,語法如下:
try
正常的操作
.................
except:
發(fā)生異常,執(zhí)行這部分代碼
.................
else:
如果沒有異常執(zhí)行這部分代碼
以上方式try-except語句捕獲所有發(fā)生的異常,但是這不是一個好的方式,我們無法通過該程序識別出具體的異常信息,因為它捕獲所有的異常。
使用except而帶多種異常類型
我們可以使用相同的except語句來處理多個異常信息,如下所示:
try:
正常的操作
......................
except(Exception1[, Exception2[,...ExceptionN]]]):
發(fā)生以上多個異常中的一個,執(zhí)行這塊代碼
......................
else:
如果沒有異常執(zhí)行這塊代碼
try-finally語句
try-finally語句無論是否發(fā)生異常都將執(zhí)行finally后的代碼:
try:
<語句>
finally:
<語句> #退出try時總會執(zhí)行
raise
如下實例:
try:
fh = open("testfile", "w")
fh.write("這是一個測試文件,用于測試異常!!")
finally:
print("Error: 沒有找到文件或讀取文件失敗")
如果打開的文件沒有可寫權(quán)限,輸出結(jié)果如下:
Error: 沒有找到文件或讀取文件失敗
上面實例,也可以寫成如下的方式:
try:
fh = open("testfile", "w")
try:
fh.write("這是一個測試文件,用于測試異常!!")
finally:
print("關(guān)閉文件")
fh.close()
except IOError:
print("Error: 沒有找到文件或讀取文件失敗")
當(dāng)在try塊中拋出一個異常,立即執(zhí)行finally代碼塊。finally塊中的所有語句執(zhí)行后,異常被再次觸發(fā),并執(zhí)行except代碼塊。
異常的參數(shù)
一個異常可以帶上參數(shù),可以作為輸出的異常信息參數(shù),我們可以通過except語句來捕獲異常的參數(shù),如下所示:
try:
正常的操作
......................
except ExceptionType, Argument:
你可以在這輸出 Argument 的值...
變量接受的異常值通常包含在異常的語句中。在元組的表單中變量可以接收一個或多個值。元組通常包含錯誤字符串,錯誤數(shù)字,錯誤位置。
以下為單個異常的實例:
def temp_convert(var):
try:
return int(var)
except ValueError as argument: #Python3
print("參數(shù)沒有包含數(shù)字
", argument)
temp_convert("abc")
運(yùn)行輸出結(jié)果為:
參數(shù)沒有包含數(shù)字
invalid literal for int() with base 10: 'abc'
觸發(fā)異常
我們可以使用raise語句自己觸發(fā)異常,其語法格式如下:
raise [Exception [, args [, traceback]]]
語句中Exception是異常的類型(例如:NameError)參數(shù)標(biāo)準(zhǔn)異常中任一種,args是自己提供的異常參數(shù)。最后一個參數(shù)是可選的(實際中很少用),如果存在,是跟蹤異常對象。
實例:一個異常可以是字符串,類或?qū)ο蟆ython提供的內(nèi)置異常,大多數(shù)都是實例化的類,這是一個類的的實例的參數(shù),異常的定義非常簡單,如下所示:
def function_name(level):
if level < 1:
raise Exception("Invalid level!", level)
# 觸發(fā)異常,后面的代碼就不會再執(zhí)行
注意:為了能夠捕獲異常,except語句必須用相同的異常來拋出類對象或字符串,例如:我們捕獲上面異常,except語句如下所示:
try:
正常邏輯
except Exception as err:
觸發(fā)自定義異常
else:
其余代碼
如下實例:
def function_name(level):
if level < 1:
raise Exception("Invalid level!", level)
# 觸發(fā)異常,后面的代碼就不會再執(zhí)行
try:
function_name(0)
except Exception as err:
print(1, err)
else:
print(2)
運(yùn)行輸出結(jié)果為:
1 ('Invalid level!', 0)
用戶自定義異常
通過創(chuàng)建一個新的異常類,程序可以命名它們自己的異常。異常應(yīng)該是典型的繼承自Exception類,通過直接或間接的方式。以下為與RuntimeError相關(guān)的實例,實例中創(chuàng)建了一個類,基類為RuntimeError,用于在異常觸發(fā)時輸出更多的信息,在try語句塊中,用戶自定義的異常后執(zhí)行except塊語句,變量e用于創(chuàng)建NetworkError類的實例:
class NetworkError(RuntimeError):
def __init__(self, arg):
self.args = arg
在定義以上類后,我們可以觸發(fā)該異常,如下所示:
try:
raise NetworkError("Bad hostname")
except NetworkError as e:
print(e.args)
總結(jié)
以上是生活随笔為你收集整理的Python 断言和异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计师可以用Epub360来做中秋节H5
- 下一篇: 消息称美国将无限期延长对三星和 SK 海