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