濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > Python異常類型以及處理方法匯總

Python異常類型以及處理方法匯總

熱門標(biāo)簽:小蘇云呼電話機(jī)器人 儋州電話機(jī)器人 地圖標(biāo)注面積 朝陽(yáng)手機(jī)外呼系統(tǒng) 佛山400電話辦理 北京電銷外呼系統(tǒng)加盟 市場(chǎng)上的電銷機(jī)器人 所得系統(tǒng)電梯怎樣主板設(shè)置外呼 北瀚ai電銷機(jī)器人官網(wǎng)手機(jī)版

前言

調(diào)試Python程序時(shí),經(jīng)常會(huì)報(bào)出一些異常,異常的原因一方面可能是寫程序時(shí)由于疏忽或者考慮不全造成了錯(cuò)誤,這時(shí)就需要根據(jù)異常Traceback到出錯(cuò)點(diǎn),進(jìn)行分析改正;另一方面,有些異常是不可避免的,但我們可以對(duì)異常進(jìn)行捕獲處理,防止程序終止。

1 異常類型

1.1 Python內(nèi)置異常

Python的異常處理能力是很強(qiáng)大的,它有很多內(nèi)置異常,可向用戶準(zhǔn)確反饋出錯(cuò)信息。在Python中,異常也是對(duì)象,可對(duì)它進(jìn)行操作。BaseException是所有內(nèi)置異常的基類,但用戶定義的類并不直接繼承BaseException,所有的異常類都是從Exception繼承,且都在exceptions模塊中定義。Python自動(dòng)將所有異常名稱放在內(nèi)建命名空間中,所以程序不必導(dǎo)入exceptions模塊即可使用異常。一旦引發(fā)而且沒有捕捉SystemExit異常,程序執(zhí)行就會(huì)終止。如果交互式會(huì)話遇到一個(gè)未被捕捉的SystemExit異常,會(huì)話就會(huì)終止。

內(nèi)置異常類的層次結(jié)構(gòu)如下:

BaseException  # 所有異常的基類
 +-- SystemExit  # 解釋器請(qǐng)求退出
 +-- KeyboardInterrupt  # 用戶中斷執(zhí)行(通常是輸入^C)
 +-- GeneratorExit  # 生成器(generator)發(fā)生異常來(lái)通知退出
 +-- Exception  # 常規(guī)異常的基類
      +-- StopIteration  # 迭代器沒有更多的值
      +-- StopAsyncIteration  # 必須通過(guò)異步迭代器對(duì)象的__anext__()方法引發(fā)以停止迭代
      +-- ArithmeticError  # 各種算術(shù)錯(cuò)誤引發(fā)的內(nèi)置異常的基類
      |    +-- FloatingPointError  # 浮點(diǎn)計(jì)算錯(cuò)誤
      |    +-- OverflowError  # 數(shù)值運(yùn)算結(jié)果太大無(wú)法表示
      |    +-- ZeroDivisionError  # 除(或取模)零 (所有數(shù)據(jù)類型)
      +-- AssertionError  # 當(dāng)assert語(yǔ)句失敗時(shí)引發(fā)
      +-- AttributeError  # 屬性引用或賦值失敗
      +-- BufferError  # 無(wú)法執(zhí)行與緩沖區(qū)相關(guān)的操作時(shí)引發(fā)
      +-- EOFError  # 當(dāng)input()函數(shù)在沒有讀取任何數(shù)據(jù)的情況下達(dá)到文件結(jié)束條件(EOF)時(shí)引發(fā)
      +-- ImportError  # 導(dǎo)入模塊/對(duì)象失敗
      |    +-- ModuleNotFoundError  # 無(wú)法找到模塊或在在sys.modules中找到None
      +-- LookupError  # 映射或序列上使用的鍵或索引無(wú)效時(shí)引發(fā)的異常的基類
      |    +-- IndexError  # 序列中沒有此索引(index)
      |    +-- KeyError  # 映射中沒有這個(gè)鍵
      +-- MemoryError  # 內(nèi)存溢出錯(cuò)誤(對(duì)于Python 解釋器不是致命的)
      +-- NameError  # 未聲明/初始化對(duì)象 (沒有屬性)
      |    +-- UnboundLocalError  # 訪問未初始化的本地變量
      +-- OSError  # 操作系統(tǒng)錯(cuò)誤,EnvironmentError,IOError,WindowsError,socket.error,select.error和mmap.error已合并到OSError中,構(gòu)造函數(shù)可能返回子類
      |    +-- BlockingIOError  # 操作將阻塞對(duì)象(e.g. socket)設(shè)置為非阻塞操作
      |    +-- ChildProcessError  # 在子進(jìn)程上的操作失敗
      |    +-- ConnectionError  # 與連接相關(guān)的異常的基類
      |    |    +-- BrokenPipeError  # 另一端關(guān)閉時(shí)嘗試寫入管道或試圖在已關(guān)閉寫入的套接字上寫入
      |    |    +-- ConnectionAbortedError  # 連接嘗試被對(duì)等方中止
      |    |    +-- ConnectionRefusedError  # 連接嘗試被對(duì)等方拒絕
      |    |    +-- ConnectionResetError    # 連接由對(duì)等方重置
      |    +-- FileExistsError  # 創(chuàng)建已存在的文件或目錄
      |    +-- FileNotFoundError  # 請(qǐng)求不存在的文件或目錄
      |    +-- InterruptedError  # 系統(tǒng)調(diào)用被輸入信號(hào)中斷
      |    +-- IsADirectoryError  # 在目錄上請(qǐng)求文件操作(例如 os.remove())
      |    +-- NotADirectoryError  # 在不是目錄的事物上請(qǐng)求目錄操作(例如 os.listdir())
      |    +-- PermissionError  # 嘗試在沒有足夠訪問權(quán)限的情況下運(yùn)行操作
      |    +-- ProcessLookupError  # 給定進(jìn)程不存在
      |    +-- TimeoutError  # 系統(tǒng)函數(shù)在系統(tǒng)級(jí)別超時(shí)
      +-- ReferenceError  # weakref.proxy()函數(shù)創(chuàng)建的弱引用試圖訪問已經(jīng)垃圾回收了的對(duì)象
      +-- RuntimeError  # 在檢測(cè)到不屬于任何其他類別的錯(cuò)誤時(shí)觸發(fā)
      |    +-- NotImplementedError  # 在用戶定義的基類中,抽象方法要求派生類重寫該方法或者正在開發(fā)的類指示仍然需要添加實(shí)際實(shí)現(xiàn)
      |    +-- RecursionError  # 解釋器檢測(cè)到超出最大遞歸深度
      +-- SyntaxError  # Python 語(yǔ)法錯(cuò)誤
      |    +-- IndentationError  # 縮進(jìn)錯(cuò)誤
      |         +-- TabError  # Tab和空格混用
      +-- SystemError  # 解釋器發(fā)現(xiàn)內(nèi)部錯(cuò)誤
      +-- TypeError  # 操作或函數(shù)應(yīng)用于不適當(dāng)類型的對(duì)象
      +-- ValueError  # 操作或函數(shù)接收到具有正確類型但值不合適的參數(shù)
      |    +-- UnicodeError  # 發(fā)生與Unicode相關(guān)的編碼或解碼錯(cuò)誤
      |         +-- UnicodeDecodeError  # Unicode解碼錯(cuò)誤
      |         +-- UnicodeEncodeError  # Unicode編碼錯(cuò)誤
      |         +-- UnicodeTranslateError  # Unicode轉(zhuǎn)碼錯(cuò)誤
      +-- Warning  # 警告的基類
           +-- DeprecationWarning  # 有關(guān)已棄用功能的警告的基類
           +-- PendingDeprecationWarning  # 有關(guān)不推薦使用功能的警告的基類
           +-- RuntimeWarning  # 有關(guān)可疑的運(yùn)行時(shí)行為的警告的基類
           +-- SyntaxWarning  # 關(guān)于可疑語(yǔ)法警告的基類
           +-- UserWarning  # 用戶代碼生成警告的基類
           +-- FutureWarning  # 有關(guān)已棄用功能的警告的基類
           +-- ImportWarning  # 關(guān)于模塊導(dǎo)入時(shí)可能出錯(cuò)的警告的基類
           +-- UnicodeWarning  # 與Unicode相關(guān)的警告的基類
           +-- BytesWarning  # 與bytes和bytearray相關(guān)的警告的基類
           +-- ResourceWarning  # 與資源使用相關(guān)的警告的基類。被默認(rèn)警告過(guò)濾器忽略。

詳細(xì)說(shuō)明請(qǐng)參考:https://docs.python.org/3/library/exceptions.html#base-classes

1.2 requests模塊的相關(guān)異常

在做爬蟲時(shí),requests是一個(gè)十分好用的模塊,所以我們?cè)谶@里專門探討一下requests模塊相關(guān)的異常。

要調(diào)用requests模塊的內(nèi)置異常,只要“from requests.exceptions import xxx”就可以了,比如:

from requests.exceptions import ConnectionError, ReadTimeout

或者直接這樣也是可以的:

from requests import ConnectionError, ReadTimeout

requests模塊內(nèi)置異常類的層次結(jié)構(gòu)如下:

IOError
 +-- RequestException  # 處理不確定的異常請(qǐng)求
      +-- HTTPError  # HTTP錯(cuò)誤
      +-- ConnectionError  # 連接錯(cuò)誤
      |    +-- ProxyError  # 代理錯(cuò)誤
      |    +-- SSLError  # SSL錯(cuò)誤
      |    +-- ConnectTimeout(+-- Timeout)  # (雙重繼承,下同)嘗試連接到遠(yuǎn)程服務(wù)器時(shí)請(qǐng)求超時(shí),產(chǎn)生此錯(cuò)誤的請(qǐng)求可以安全地重試。
      +-- Timeout  # 請(qǐng)求超時(shí)
      |    +-- ReadTimeout  # 服務(wù)器未在指定的時(shí)間內(nèi)發(fā)送任何數(shù)據(jù)
      +-- URLRequired  # 發(fā)出請(qǐng)求需要有效的URL
      +-- TooManyRedirects  # 重定向太多
      +-- MissingSchema(+-- ValueError) # 缺少URL架構(gòu)(例如http或https)
      +-- InvalidSchema(+-- ValueError) # 無(wú)效的架構(gòu),有效架構(gòu)請(qǐng)參見defaults.py
      +-- InvalidURL(+-- ValueError)  # 無(wú)效的URL
      |    +-- InvalidProxyURL  # 無(wú)效的代理URL
      +-- InvalidHeader(+-- ValueError)  # 無(wú)效的Header
      +-- ChunkedEncodingError  # 服務(wù)器聲明了chunked編碼但發(fā)送了一個(gè)無(wú)效的chunk
      +-- ContentDecodingError(+-- BaseHTTPError)  # 無(wú)法解碼響應(yīng)內(nèi)容
      +-- StreamConsumedError(+-- TypeError)  # 此響應(yīng)的內(nèi)容已被使用
      +-- RetryError  # 自定義重試邏輯失敗
      +-- UnrewindableBodyError  # 嘗試倒回正文時(shí),請(qǐng)求遇到錯(cuò)誤
      +-- FileModeWarning(+-- DeprecationWarning)  # 文件以文本模式打開,但Requests確定其二進(jìn)制長(zhǎng)度
      +-- RequestsDependencyWarning  # 導(dǎo)入的依賴項(xiàng)與預(yù)期的版本范圍不匹配
 
Warning
 +-- RequestsWarning  # 請(qǐng)求的基本警告 

詳細(xì)說(shuō)明及源碼請(qǐng)參考:http://www.python-requests.org/en/master/_modules/requests/exceptions/#RequestException

下面是一個(gè)簡(jiǎn)單的小例子,python內(nèi)置了一個(gè)ConnectionError異常,這里可以不用再?gòu)膔equests模塊import了:

import requests
from requests import ReadTimeout
 
 
def get_page(url):
 try:
  response = requests.get(url, timeout=1)
  if response.status_code == 200:
   return response.text
  else:
   print('Get Page Failed', response.status_code)
   return None
 except (ConnectionError, ReadTimeout):
  print('Crawling Failed', url)
  return None
 
 
def main():
 url = 'https://www.baidu.com'
 print(get_page(url))
 
 
if __name__ == '__main__':
 main()

1.3 用戶自定義異常

此外,你也可以通過(guò)創(chuàng)建一個(gè)新的異常類擁有自己的異常,異常應(yīng)該是通過(guò)直接或間接的方式繼承自Exception類。下面創(chuàng)建了一個(gè)MyError類,基類為Exception,用于在異常觸發(fā)時(shí)輸出更多的信息。

  在try語(yǔ)句塊中,拋出用戶自定義的異常后執(zhí)行except部分,變量 e 是用于創(chuàng)建MyError類的實(shí)例。

class MyError(Exception):
	def __init__(self, msg):
		self.msg = msg
	
	def __str__(self):
		return self.msg
 
 
try:
	raise MyError('類型錯(cuò)誤')
except MyError as e:
	print('My exception occurred', e.msg)
 

2. 異常捕獲

當(dāng)發(fā)生異常時(shí),我們就需要對(duì)異常進(jìn)行捕獲,然后進(jìn)行相應(yīng)的處理。python的異常捕獲常用try...except...結(jié)構(gòu),把可能發(fā)生錯(cuò)誤的語(yǔ)句放在try模塊里,用except來(lái)處理異常,每一個(gè)try,都必須至少對(duì)應(yīng)一個(gè)except。此外,與python異常相關(guān)的關(guān)鍵字主要有:

關(guān)鍵字 關(guān)鍵字說(shuō)明
try/except 捕獲異常并處理
pass 忽略異常
as 定義異常實(shí)例(except MyError as e)
else 如果try中的語(yǔ)句沒有引發(fā)異常,則執(zhí)行else中的語(yǔ)句
finally 無(wú)論是否出現(xiàn)異常,都執(zhí)行的代碼
raise     拋出/引發(fā)異常

異常捕獲有很多方式,下面分別進(jìn)行討論。

2.1 捕獲所有異常

包括鍵盤中斷和程序退出請(qǐng)求(用sys.exit()就無(wú)法退出程序了,因?yàn)楫惓1徊东@了),因此慎用。

try:
     語(yǔ)句>
 
except:
 
      print('異常說(shuō)明')

2.2 捕獲指定異常

try:
     語(yǔ)句>
 
except 異常名>:
 
      print('異常說(shuō)明')

萬(wàn)能異常:

try:
     語(yǔ)句>
 
except Exception:
 
      print('異常說(shuō)明')

一個(gè)例子:

try:
    f = open("file-not-exists", "r")
 
except IOError as e:
 
    print("open exception: %s: %s" %(e.errno, e.strerror))

2.3 捕獲多個(gè)異常

捕獲多個(gè)異常有兩種方式,第一種是一個(gè)except同時(shí)處理多個(gè)異常,不區(qū)分優(yōu)先級(jí):

try:
     語(yǔ)句>
 
except (異常名1>, 異常名2>, ...):
 
      print('異常說(shuō)明')

第二種是區(qū)分優(yōu)先級(jí)的:

try:
     語(yǔ)句>
 
except 異常名1>:
 
      print('異常說(shuō)明1')
 
except 異常名2>:
 
      print('異常說(shuō)明2')
 
except 異常名3>:
 
      print('異常說(shuō)明3')

該種異常處理語(yǔ)法的規(guī)則是:

  • 執(zhí)行try下的語(yǔ)句,如果引發(fā)異常,則執(zhí)行過(guò)程會(huì)跳到第一個(gè)except語(yǔ)句。
  • 如果第一個(gè)except中定義的異常與引發(fā)的異常匹配,則執(zhí)行該except中的語(yǔ)句。
  • 如果引發(fā)的異常不匹配第一個(gè)except,則會(huì)搜索第二個(gè)except,允許編寫的except數(shù)量沒有限制。
  • 如果所有的except都不匹配,則異常會(huì)傳遞到下一個(gè)調(diào)用本代碼的最高層try代碼中。

2.4 異常中的else

如果判斷完沒有某些異常之后還想做其他事,就可以使用下面這樣的else語(yǔ)句。

try:
     語(yǔ)句>
 
except 異常名1>:
 
      print('異常說(shuō)明1')
 
except 異常名2>:
 
      print('異常說(shuō)明2')
 
else:
 
      語(yǔ)句>  # try語(yǔ)句中沒有異常則執(zhí)行此段代碼

2.5 異常中的finally

try...finally...語(yǔ)句無(wú)論是否發(fā)生異常都將會(huì)執(zhí)行最后的代碼。

try:
     語(yǔ)句>
 
finally:
 
      語(yǔ)句>

看一個(gè)示例:

str1 = 'hello world'
try:
    int(str1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
else:
    print('try內(nèi)沒有異常')
finally:
    print('無(wú)論異常與否,都會(huì)執(zhí)行我')

2.6 raise主動(dòng)觸發(fā)異常

可以使用raise語(yǔ)句自己觸發(fā)異常,raise語(yǔ)法格式如下:

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

語(yǔ)句中Exception是異常的類型(例如ValueError),參數(shù)是一個(gè)異常參數(shù)值。該參數(shù)是可選的,如果不提供,異常的參數(shù)是"None"。最后一個(gè)參數(shù)是跟蹤異常對(duì)象,也是可選的(在實(shí)踐中很少使用)。

看一個(gè)例子:

def not_zero(num):
    try:
        if num == 0:
            raise ValueError('參數(shù)錯(cuò)誤')
        return num
    except Exception as e:
        print(e)
 
 
not_zero(0)
 

2.7 采用traceback模塊查看異常

發(fā)生異常時(shí),Python能“記住”引發(fā)的異常以及程序的當(dāng)前狀態(tài)。Python還維護(hù)著traceback(跟蹤)對(duì)象,其中含有異常發(fā)生時(shí)與函數(shù)調(diào)用堆棧有關(guān)的信息。記住,異??赡茉谝幌盗星短纵^深的函數(shù)調(diào)用中引發(fā)。程序調(diào)用每個(gè)函數(shù)時(shí),Python會(huì)在“函數(shù)調(diào)用堆?!钡钠鹗继幉迦牒瘮?shù)名。一旦異常被引發(fā),Python會(huì)搜索一個(gè)相應(yīng)的異常處理程序。如果當(dāng)前函數(shù)中沒有異常處理程序,當(dāng)前函數(shù)會(huì)終止執(zhí)行,Python會(huì)搜索當(dāng)前函數(shù)的調(diào)用函數(shù),并以此類推,直到發(fā)現(xiàn)匹配的異常處理程序,或者Python抵達(dá)主程序?yàn)橹?。這一查找合適的異常處理程序的過(guò)程就稱為“堆棧輾轉(zhuǎn)開解”(StackUnwinding)。解釋器一方面維護(hù)著與放置堆棧中的函數(shù)有關(guān)的信息,另一方面也維護(hù)著與已從堆棧中“輾轉(zhuǎn)開解”的函數(shù)有關(guān)的信息。

格式如下:

try:
    block
 
except:
 
    traceback.print_exc()

舉個(gè)栗子:

try:
    1/0
except Exception as e:
    print(e)

如果我們這樣寫的話,程序只會(huì)報(bào)“division by zero”錯(cuò)誤,但是我們并不知道是在哪個(gè)文件哪個(gè)函數(shù)哪一行出的錯(cuò)。

下面使用traceback模塊,官方參考文檔:https://docs.python.org/2/library/traceback.html

import traceback
 
try:
    1/0
except Exception as e:
    traceback.print_exc()

這樣就會(huì)幫我們追溯到出錯(cuò)點(diǎn):

Traceback (most recent call last):
  File "E:/PycharmProjects/ProxyPool-master/proxypool/test.py", line 4, in module>
    1/0
ZeroDivisionError: division by zero

另外,traceback.print_exc()跟traceback.format_exc()有什么區(qū)別呢?

區(qū)別就是,format_exc()返回字符串,print_exc()則直接給打印出來(lái)。即traceback.print_exc()與print(traceback.format_exc())效果是一樣的。print_exc()還可以接受file參數(shù)直接寫入到一個(gè)文件。比如可以像下面這樣把相關(guān)信息寫入到tb.txt文件去。

traceback.print_exc(file=open('tb.txt','w+'))

參考博文:

except as e中的‘e'的作用總結(jié)

python使用traceback獲取詳細(xì)的異常信息

總結(jié)

到此這篇關(guān)于Python異常類型以及處理方法的文章就介紹到這了,更多相關(guān)Python異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 詳解Python魔法方法之描述符類
  • Python繪制分類圖的方法
  • python迭代器自定義類的具體方法
  • Python類型轉(zhuǎn)換的魔術(shù)方法詳解
  • class類在python中獲取金融數(shù)據(jù)的實(shí)例方法
  • Python類綁定方法及非綁定方法實(shí)例解析
  • 利用python批量爬取百度任意類別的圖片的實(shí)現(xiàn)方法
  • Python類方法總結(jié)講解

標(biāo)簽:商丘 酒泉 龍巖 寧夏 金融催收 江蘇 云南 定西

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Python異常類型以及處理方法匯總》,本文關(guān)鍵詞  Python,異常,類型,以及,處理,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Python異常類型以及處理方法匯總》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Python異常類型以及處理方法匯總的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    武宣县| 中阳县| 富平县| 荃湾区| 祥云县| 洛阳市| 满洲里市| 西藏| 田林县| 西华县| 枣强县| 揭东县| 彰化市| 呼玛县| 横峰县| 巫溪县| 永宁县| 靖宇县| 余姚市| 郯城县| 涞水县| 乌兰县| 石柱| 嘉黎县| 广水市| 云和县| 旅游| 三原县| 黔西县| 乌什县| 新乡县| 苏尼特右旗| 米林县| 济源市| 贺兰县| 厦门市| 合川市| 玉门市| 景洪市| 永昌县| 甘泉县|