16.python異常處理

来源:https://www.cnblogs.com/bonheur/archive/2020/02/28/12374383.html
-Advertisement-
Play Games

異常處理涉及的關鍵字: try: 理解它是掃描器,將可能出現異常的代碼放入其中; 如果在執行的過程中出現異常對象了,掃描器會立即察覺到此異常對象, 但是它沒有處理它的能力,所以會將異常對象給到except(捕獲器)進行處理 except: 理解它是捕獲器,後面可以定義異常類型,並且和as關鍵字配合使 ...


Python 有兩種錯誤很容易辨認:語法錯誤和異常(本文將重點介紹python的異常)。

 

python語法錯誤:

Python 的語法錯誤或者稱之為解析錯,是初學者經常碰到的;

>>>while True print('Hello world')
  File "<stdin>", line 1, in ?
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

函數 print() 被檢查到有錯誤,是它前面缺少了一個冒號 :語法分析器指出了出錯的一行,並且在最先找到的錯誤的位置標記了一個小小的箭頭。

 

python異常:

即便 Python 程式的語法是正確的,在運行它的時候,也有可能發生錯誤。運行期檢測到的錯誤被稱為異常。異常即是一個事件,該事件會在程式執行過程中發生,影響了程式的正常執行;一般情況下,在Python無法正常處理程式時就會發生一個異常;異常是Python對象,表示一個錯誤;當Python腳本發生異常時我們需要捕獲處理它,否則程式會終止執行。

>>>10 * (1/0)                         # 0 不能作為除數,觸發異常
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3 # spam 未定義,觸發異常 Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'spam' is not defined
>>> '2' + 2 # int 不能與 str 相加,觸發異常 Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: Can't convert 'int' object to str implicitly

異常以不同的類型出現,這些類型都作為信息的一部分列印出來: 例子中的類型有 ZeroDivisionError,NameError 和 TypeError。錯誤信息的前面部分顯示了異常發生的上下文,並以調用棧的形式顯示具體信息。

 

python異常的處理:

python提供了兩個非常重要的功能來處理python程式在運行中出現的異常和錯誤。你可以使用該功能來調試python程式。異常處理斷言(Assertions)

 

異常處理涉及的5個關鍵字:

try理解它是掃描器,將可能出現異常的代碼放入其中;如果在執行的過程中出現異常對象了,掃描器會立即察覺到此異常對象,但是它沒有處理它的能力,所以會將異常對象給到except(捕獲器)進行處理。

except理解它是捕獲器,後面可以定義異常類型,並且和as關鍵字配合使用;定義多個except是合法的,但是它的執行順序是有由上往下,一旦匹配上某個except,之後的就不執行了;匹配成功就理解將異常對象捕獲住並且kill,順便會執行except內部的代碼。(註意:except不能捕獲處理類似於語法錯誤這種情況)

finally將一定需要被執行的代碼定義其中,【記住】:finally一定會被執行(核心);使用場景:像關閉文件、斷開資料庫連接等行為都可以放入到finally中。

else位置在finally前,except後;效果/作用類似於迴圈;沒有異常對象出現,else就會被執行,反之不會被執行。

raise手動拋出一個異常類型的對象,定義:raise 異常類型(msg)。

 

定義格式:

格式一:  多個except語句併列存在,每個except包含一種類型,如果它們之間沒有子父類的關係(互斥),那麼誰上誰下無所謂, 如果它們之間存在子父類的關係(包含),那麼小的在上,大的在下。

try:
        語句塊1
except 異常類型1 as e:
        語句塊2                              
except 異常類型2 as e:
        語句塊3              
except 異常類型3 as e:
        語句塊4
finally:
        語句塊5       

 

格式二:一個except具備多個捕獲能力(捕獲多種不同類型異常對象)。

try:
         語句塊1
except 異常類型1 as e:
         語句塊2                              
except 異常類型2 as e:
         語句塊3              
except 異常類型3 as e:
         語句塊4
except (異常類型4,異常類型5,...,異常類型m) as e:
finally:
         語句塊5                                        

 

格式三:Exception是所有異常類型的父類型,它都是定義在最後一個except的位置。         

try:
        語句塊1
except 異常類型1 as e:
        語句塊2                              
except 異常類型2 as e:
        語句塊3              
except 異常類型3 as e:
        語句塊4
except (異常類型4,異常類型5,...,異常類型m) as e:
        語句塊5
except Exception as e:
        語句塊6
finally:
              語句塊7

                

格式四: 【Exception的簡化版使用】:如果定義了except,那麼它必須是最後一個except,它可以理解為是Exception的簡化形式         

try:
        語句塊1
except 異常類型1 as e:
        語句塊2                              
except 異常類型2 as e:
        語句塊3              
except 異常類型3 as e:
        語句塊4
except (異常類型4,異常類型5,...,異常類型m) as e:
        語句塊5
except:
        語句塊6
finally:
        語句塊7              

            

 代碼演示自動拋出異常對象:

 2 
 3 def div(a,b):
 4     print(a / b)
 5 
 6 div(10,0)
 7 
 8 # 演示異常處理的方式一:try ... except ...
 9 try:
10      print(10/0)
11 except ZeroDivisionError as e:
12      print(e)
13 
14 try:
15     print("abc"+123)
16 except TypeError as e:
17     print(e)
18 
19 try:
20     print(a)
21 except NameError as e:
22     print(e)
23 
24 try:
25     lt = [1,2,3,4,5]
26     print(lt[5])
27 except IndexError as e:
28     print(e)
29 
30 try:
31     fr = open(r'C:\Users\Administrator\Desktop\kaifanglist1.txt','r',encoding='utf-8')
32     print(fr.read())
33     fr.close()
34 except FileNotFoundError as e:
35     print(e)
36 
37 except(ZeroDivisionError,TypeError,NameError,IndexError,FileNotFoundError) as e:
38      print('我能捕獲5種類型的異常對象...')
39  
40 except Exception as e:
41      print('我是所有異常類型的父類型,我能解決所有的異常類型對象...')
42  
43 except:
44     print('我是Exception的簡化形式,我只能出現在最後一個except的位置...')

 

代碼演示finally語句的使用:將一定要被執行的代碼定義在finally中,不管之前的代碼怎麼樣(異常是否被解決),finally一定會被執行,在後期的學習和開發中,我們將關閉文件、關閉資料庫連接等操作都定finally中。

 1 try:
 2      fr = open(r'C:\Users\Administrator\Desktop\a.txt','r')       # 文件能打開
 3      print(fr.read())
 4      print(10 / 0)
 5      # fr.close()        # 因為關閉文件操作是一定要被執行的 但是在try裡面也有可能存在風險性,當print(10 / 0)行不了,則無法執行close操作,所以關閉文件需要放在finally語句當中
6 except: 7 print('解決異常') 8 finally: 9 print('我是finally,我一定會被執行...') 10 fr.close() 11 12 13 # 但是如果一開始就是一個打不開的文件,則也沒有辦法關閉文件 14 fr = 0 15 try: 16 fr = open(r'C:\Users\Administrator\Desktop\a111.txt','r') # 沒有此文件名 (文件存在則fr不為None值) 17 print(fr.read()) 18 except: 19 print('解決異常') 20 finally: 21 print('我是finally,我一定會被執行...') 22 if fr: # fr為None值則if為False,否則為True,執行以下指令(為了安全性) 23 fr.close()

finally案例演示二(進一步理解):

 1 # Finally案例:分別輸出了哪些內容,返回值是多少
 2 
 3 def func():
 4     try:
 5         print('我是try...')
 6         print(10 / 2)
 7         return 1       #執行此步 則函數就結束了,又因為finally一定要被執行,所以return 1不會被執行,直接調到finally
 8     except:
 9         print('我是except...')
10         return 2
11     finally:
12         print('我是finally...')
13         return 3
14 
15 num = func()
16 print(num)
17 '''結果得到是       
18 我是try...
19 5.0
20 我是finally...
21 3'''
22 
23 # 如果題目改為如下,則
24 def func():
25     try:
26         print('我是try...')
27         print(10 / 0)
28         return 1
29     except:
30         print('我是except...')
31         return 2     #執行此步 則函數就結束了,又因為finally一定要被執行,所以return 2不會被執行,直接調到finally
32     finally:
33         print('我是finally...')
34         return 3
35 
36 num = func()
37 print(num)
38 '''結果得到是       
39 我是try...
40 我是except...
41 我是finally...
42 3'''
43

 

【補充】with open...操作:不需要程式員人為的去書寫 close() 函數

1 With open(r'C:\Users\Administrator\Desktop\a.txt','r')as fr:
2     print(fr.read())

解決異常也是一樣:

1 try:
2     with open(r'C:\Users\Administrator\Desktop\a.txt','r') as fr:
3         print(fr.read())
4 except:
5     print('解決異常...')

 

代碼演示else語句和異常處理機制配合使用:如果try中沒有出現異常對象,那麼else語句就一定會被執行,如果try中出現了異常對象,就算被處理了,else還是不會被執行。

 1 try:
 2     print('我是try...')
 3     print(10 / 0)  
 4 except Exception as e:
 5     print('我是except...')
 6 else:
 7     print('我是else...')
 8 finally:
 9     print('我是finally...')
10 #得到 11 我是try... 12 我是except... 13 我是finally... 14 15 #如果把print(10 / 0) 改為print(10 / 2) 16 17 #得到 18 我是try... 19 5.0 20 我是else... 21 我是finally...


代碼演示raise的使用:(手動拋出異常對象)

 1 age = 18 
 2 if age < 0 or age > 130:
 3      try:         
 4           raise Exception('年齡有問題...')     
 5      except:         
 6           print('年齡不合法...正在處理')         
 7           pass 
 8 else:     
 9      print('年齡為:%d' %age)
10 print('能走嗎?')
11 
12 #得到結果為     
13 年齡為:18
14 能走嗎?
15 
16 #如果第一行是age=-18
17 #得到結果為     
18 年齡不合法...正在處理
19 能走嗎?

 

 1 # 演示異常處理的方式二:不斷往上級傳遞異常對象,迴避問題的方式
 2 
 3 def m1():
 4     print('我是m1...')
 5     print(10 / 0)
 6 
 7 def m2():
 8     print('我是m2...')
 9     # try:
10     m1()
11     # except:
12     #     pass
13 
14 def m3():
15     print('我是m3...')
16     try:
17         m2()
18     except:
19         pass
20 
21 m3()
22 #得到結果  
23 我是m3...
24 我是m2...
25 我是m1...

 

python標準異常總結:

BaseException 所有異常的基類
SystemExit 解釋器請求退出
KeyboardInterrupt 用戶中斷執行(通常是輸入^C)
Exception 常規錯誤的基類
StopIteration 迭代器沒有更多的值
GeneratorExit 生成器(generator)發生異常來通知退出
StandardError 所有的內建標準異常的基類
ArithmeticError 所有數值計算錯誤的基類
FloatingPointError 浮點計算錯誤
OverflowError 數值運算超出最大限制
ZeroDivisionError 除(或取模)零 (所有數據類型)
AssertionError 斷言語句失敗
AttributeError 對象沒有這個屬性
EOFError 沒有內建輸入,到達EOF 標記
EnvironmentError 操作系統錯誤的基類
IOError 輸入/輸出操作失敗
OSError 操作系統錯誤
WindowsError 系統調用失敗
ImportError 導入模塊/對象失敗
LookupError 無效數據查詢的基類
IndexError 序列中沒有此索引(index)
KeyError 映射中沒有這個鍵
MemoryError 記憶體溢出錯誤(對於Python 解釋器不是致命的)
NameError 未聲明/初始化對象 (沒有屬性)
UnboundLocalError 訪問未初始化的本地變數
ReferenceError 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象
RuntimeError 一般的運行時錯誤
NotImplementedError 尚未實現的方法
SyntaxError Python 語法錯誤
IndentationError 縮進錯誤
TabError Tab 和空格混用
SystemError 一般的解釋器系統錯誤
TypeError 對類型無效的操作
ValueError 傳入無效的參數
UnicodeError Unicode 相關的錯誤
UnicodeDecodeError Unicode 解碼時的錯誤
UnicodeEncodeError Unicode 編碼時錯誤
UnicodeTranslateError Unicode 轉換時錯誤
Warning 警告的基類
DeprecationWarning 關於被棄用的特征的警告
FutureWarning 關於構造將來語義會有改變的警告
OverflowWarning 舊的關於自動提升為長整型(long)的警告
PendingDeprecationWarning 關於特性將會被廢棄的警告
RuntimeWarning 可疑的運行時行為(runtime behavior)的警告
SyntaxWarning 可疑的語法的警告
UserWarning 用戶代碼生成的警告

 

註意事項】:

1).try...finally這種格式是合法的,但是它喪失瞭解決異常對象的能力(所以不會使用)

2).else語句必須配合except使用,出現位置一定是在最後一個except的後面

3).常見的運行時異常類型:ZeroDivisionError:分母為0的異常;TypeError:類型有誤的異常; NameError:沒有定義就使用的異常;IndexError:下標越界的異;FileNotFoundError:文件找不到的異常;...

4).with open ... as ...語句可以優化原始的open操作!體現:它不需要手動close()文件對象

 

總結:學習異常對象簡單歸納為5個關鍵字:try except finally else raise

 

python的assert(斷言):

Python的assert(斷言)用於判斷一個表達式,在表達式條件為 false 的時候觸發異常。斷言可以在條件不滿足程式運行的情況下直接返回錯誤,而不必等待程式運行後出現崩潰的情況,例如我們的代碼只能在 Linux 系統下運行,可以先判斷當前系統是否符合條件。

語法格式如下:assert expression

等價於:

if not expression:

        raise AssertionError

assert 後面也可以緊跟參數: assert expression [, arguments]

等價於:

if not expression:

        raise AssertionError(arguments)

 

代碼演示assert示例:

 1 >>> assert True     # 條件為 true 正常執行
 2 >>> assert False    # 條件為 false 觸發異常
 3 Traceback (most recent call last):
 4   File "<stdin>", line 1, in <module>
 5 AssertionError
 6 
 7 >>> assert 1==1    # 條件為 true 正常執行
 8 >>> assert 1==2    # 條件為 false 觸發異常
 9 Traceback (most recent call last):
10   File "<stdin>", line 1, in <module>
11 AssertionError
12 
13 >>> assert 1==2, '1 不等於 2'
14 Traceback (most recent call last):
15   File "<stdin>", line 1, in <module>
16 AssertionError: 1 不等於 2
17 
18 
19 # 判斷當前系統是否為 Linux,如果不滿足條件則直接觸發異常,不必執行接下來的代碼:
20 import sys
21 assert ('linux' in sys.platform), "該代碼只能在 Linux 下執行"
22 # 接下來要執行的代碼

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、 安裝環境 python2.7.15(我使用的版本是歷史版本,比較晚) a. 在python官網下載對應版本(相容性需要自行確定),推薦使用虛擬機中共用軟體的功能(我的共用軟體是掛載到"/mnt/hgfs/",當進入目錄後會看到'你的共用文件的名字'直接進去就可以)。 b. sudo tar - ...
  • 我的潘多拉 從一個故事說起。從前,有個Java程式員非常喜歡寫程式,喜歡研究源碼,讀英文文檔。但是它在一家小公司里工作,公司的技術棧很陳舊。 單個系統代碼中含有很多的xml配置,配置各種中間件的入口適配器,而不同的業務系統中都是類似的配置。啟動單個系統很慢。啟動依賴web組件,無法快速部署。公共組件 ...
  • python3-cookbook中每個小節以問題、解決方案和討論三個部分探討了Python3在某類問題中的最優解決方式,或者說是探討Python3本身的數據結構、函數、類等特性在某類問題上如何更好地使用。這本書對於加深Python3的理解和提升Python編程能力的都有顯著幫助,特別是對怎麼提高Py ...
  • 一、 1.讓SortedSet集合做到排序還有另一種方式:java.util.Comparator; 2.單獨編寫一個比較器 package com.bjpowernode.java_learning; import java.util.*; ​ public class D90_1_SortedS ...
  • 明確學習目標,不急於求成 當下是一個喧囂、浮躁的時代。我們總是被生活中大量涌現的熱點所吸引,幾乎沒有深度閱讀和思考的時間和機會。我始終認為,學習是需要沉下心來慢慢鑽研的,是長 期的;同時,學習不應該被賦予太多的功利色彩。一個Python 程式員的成長路線圖應該是這樣子的:基礎語法–>語感訓練–>課題 ...
  • python3-cookbook中每個小節以問題、解決方案和討論三個部分探討了Python3在某類問題中的最優解決方式,或者說是探討Python3本身的數據結構、函數、類等特性在某類問題上如何更好地使用。這本書對於加深Python3的理解和提升Python編程能力的都有顯著幫助,特別是對怎麼提高Py ...
  • 基於JSP+Servlet開發超市日常管理系統: 開發環境: Windows操作系統開發工具: Eclipse+Jdk+Tomcat+MYSQL資料庫題目:根據超市日常所做的工作描述,結合超市經理提出的超市管理需求,本超市管理系統主要提供以下功能:超市經理能夠進行商品的添加、商品的查看,商品的信息修 ...
  • 基於JSP+Servlet開發學生成績管理系統 開發環境: Windows操作系統開發工具: MyEclipse+Jdk+Tomcat+Mysql資料庫運行效果圖 源碼及原文鏈接:https://javadao.xyz/forum.php?mod=viewthread&tid=57 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...