python的錯誤和異常


python錯誤和異常

錯誤

錯誤分為語法錯誤和邏輯錯誤

語法錯誤

>>> if
  File "<stdin>", line 1
    if
     ^
SyntaxError: invalid syntax

程序執行過程中,python解釋器會檢測你的程序是否存在語法錯誤,如果程序出錯python解釋器會指出出錯的一行,並且在最先找到的 錯誤的文職標記了一個小小的箭頭。

邏輯錯誤

>>> 1/0Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

在生活中0是不能作為被除數的,程序寫的語法可能沒問題,但是邏輯上不一定沒有問題。這就是一種邏輯錯誤。

 

異常

即便python的程序的語法是正確的,在運行它的時候,也有可能發生錯誤,程序運行期檢測到的錯誤被稱為異常。

異常是有錯誤產生的。

程序出現了異常都不會被程序處理,都以錯誤信息的會展現出來。

>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4+"xi"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> li = [1,2,3,4]
>>> li[1]
2
>>> li[10]
Traceback (most recent call last):  #Trackback,追溯到最近的錯誤信息
  File "<stdin>", line 1, in <module>
IndexError: list index out of range   #IndexError 異常類  冒號后面是異常的值

異常都有不同的類型出現,這些錯誤類型都作為信息的一部分打印出來,例子中的類型有ZeroDivisionError,TypeError,IndexError。每一種錯誤類型,都有相應的異常類。

python中的異常類

在python中不同的異常可以用不同的類型(類型即類)去標識,不同的類的對象標識了不同的異常,一個異常標識一種錯誤。

python中所有的錯誤都是從BaseException類派生的

常見的錯誤類型和繼承關系:點擊

 

異常處理

程序出現了錯誤,肯定需要去進行異常處理。

 

什么是異常處理:

python解釋器檢測到錯誤,觸發異常。

程序員編寫特定的代碼,專門用來捕捉這個異常(這段代碼與程序邏輯無關,與異常處理有關)

如果捕捉成功則進入另外一個處理分支,執行你為其定制的邏輯,使程序不會崩潰,這就是異常處理

為何進行異常處理:

誰會用一個報錯的程序,更何況使用者又不知道怎么解決,一運行就報錯,誰用你的程序或則軟件。

所以就必須提供一種異常處理機制來完善程序的容錯性。

 

 

如何解決異常處理?

異常是有程序的錯誤引起的,語法上的錯誤跟異常處理無關,必須在程序運行前就修正。

 

在以前學程序的時候,經常使用if判斷來做異常解決。

但是:

1if判斷是的異常處理只能針對某一段代碼,對於不同的代碼段的相同類型的錯誤需要些重復的if來進行處理。

2在程序中頻繁的寫與程序本身無關,與異常處理有關的if,這樣代碼的可讀性非常的差。

 

 

try   except  異常處理

python為每一種異常定制一個類型,然后提供了一種特定的語法結構來用來進行異常處理

基本語法

try:
     被檢測的代碼塊
except 異常類型:
     try中一旦檢測到異常,就執行這個位置的邏輯

  

異常的類只能用來處理指定的異常情況,如果非指定異常則無法處理。

while True:
        try:
            x = int(input("Please enter a number: "))
            break
        except ValueError    as err:  #這里相當於把 ValueError 改名為err
            print("Oops!  That was no valid number.  Try again   ")

 

一個try語句可以包含多個except字句,分別來處理不同的特定的異常,最多只有一個分支except會被執行。(相當於,if  elif  elif )

 

處理程序只針對對應的try字句中的異常處理,而不是其他的try的處理程序中的異常。

一個except字句中可以同時處理多個異常,這些異常被放在一個括號里成為一個元祖,例如:

 except (ValueError, TypeError, NameError):
        pass

 

最后一個except字句可以忽略異常的名稱,它將被作為通配符使用,可以使用這種方法打印一個錯誤信息,然后再次把異常拋出。

li = [1,2,3,4,"a"]

try:
    li[0]
    int(li[-1])
    li[12]
except IndexError as err:
    print(err,"該索引超出范圍")
except:
    print("不能int")
    raise #拋出異常, 遇到程序錯誤,結束這個程序,拋出程序異常的錯誤信息。

 

萬能異常

 

li = [1,2,3,4,"a"]

try:
    li[0]
    int(li[-1])
    li[12]
except IndexError as err:
    print(err,"該索引超出范圍")
except  Exception:   #Exception  萬能異常包含所有的異常
    print("不能int")
    #raise #拋出異常, 遇到程序錯誤,結束這個程序,拋出程序異常的錯誤信息。

#跟最后一個except子句一樣,都是一樣的效果。

 

如果需要查看錯誤類型,可以用raise拋出異常。

 

什么時候用萬能異常?

對於不同的異常,我們需要定制不同處理邏輯,那就需要用多分支,對於未知的異常可以用萬能異常。

 

try except 語句還有一個可選的else子句,如果使用這個子句,那么必須放在所有的except子句之后。這個else子句將在try子句沒有發生任何異常的時候執行。例如:

 

while True:
        try:
            x = int(input("Please enter a number: "))

        except ValueError    as err:  #這里相當於把 ValueError 改名為err
            print("Oops!  That was no valid number.  Try again   ")
        else:
            print("hello world")
            break

  

try except else finally

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
#except Exception as e:
#    print(e)
else:
    print('try內代碼塊沒有異常則執行我')
finally:
    print('無論異常與否,都會執行該finall語句,通常是進行清理工作')

 

自定義異常

class MyError(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return str(self.value)


try:
    raise MyError(2 * 2)  #拋出異常   相當於try句中有錯誤,交給except句
except MyError as e:       #自定義異常觸發
    print('My exception occurred, value:', e.value)

  

class MyError(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return str(self.value)


try:
    raise MyError(2 * 2)  #拋出異常   相當於try句中有錯誤,交給except句
except MyError as e:       #自定義異常觸發
    print('My exception occurred, value:', e.value)

raise MyError ("自已定義的異常")

#錯誤信息
"""
Traceback (most recent call last):
  File "D:/learn/week4/文件.py", line 16, in <module>
    raise MyError ("自已定義異常")
__main__.MyError: 自已定義異常
"""

  

if 和 try..except比較 

異常處理中為每一個異常定制了異常類型(python中統一了類與類型,類型即類),對於同一種異常,一個except就可以捕捉到,可以同時處理多段代碼的異常(無需‘寫多個if判斷式’)減少了代碼,增強了可讀性 

 

最后總結:

什么時候用異常處理?

try...except應該盡量少用,因為它本身就是你附加給你的程序的一種異常處理的邏輯,與你的主要的工作是沒有關系的
這種東西加的多了,會導致你的代碼可讀性變差

只有在有些異常無法預知的情況下,才應該加上try...except,其他的邏輯錯誤應該盡量修正

 

Python內置的try...except...finally用來處理錯誤十分方便。出錯時,會分析錯誤信息並定位錯誤發生的代碼位置才是最關鍵的。

程序也可以主動拋出錯誤,讓調用者來處理相應的錯誤。但是,應該在文檔中寫清楚可能會拋出哪些錯誤,以及錯誤產生的原因。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM