Python 斷言和異常

Python 斷言和異常

<font color=red size=4>Python斷言</font>

斷言是一種理智檢查,當程序的測試完成,能夠將其打開或關閉。斷言的最簡單方法就是把它比做raise-if語句(或更加準確,raise-if-not聲明)。一個表達式進行測試,若是結果出現false,將引起異常。程序中經常放置斷言來檢查輸入的有效與否,或在一個函數調用後檢查有效的輸出,其爲assert關鍵字構成的語句。 assert語句</font> 但它遇到一個斷言語句,Python評估計算以後的表達式,但願是true。若是是表達式爲false,Python觸發AssertionError異常,其語法是:python

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!

<font color=red size=4>Python 異常處理</font>

Python提供的標準異常以下列表:spa

異常名稱 描述
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裏捕獲它,其語法格式以下:code

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("參數沒有包含數字\n", argument)


temp_convert("abc")

運行輸出結果爲:

參數沒有包含數字
invalid literal for int() with base 10: 'abc'

觸發異常 咱們可使用raise語句本身觸發異常,其語法格式以下:

raise [Exception [, args [, traceback]]]

語句中Exception是異常的類型(例如:NameError)參數標準異常中任一種,args是本身提供的異常參數。最後一個參數是可選的(實際中不多用),若是存在,是跟蹤異常對象。

實例:一個異常能夠是字符串,類或對象。Python提供的內置異常,大多數都是實例化的類,這是一個類的的實例的參數,異常的定義很是簡單,以下所示:

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)
相關文章
相關標籤/搜索