a、首先,執行 try 子句(關鍵字 try 和關鍵字 except 之間的語句)
b、若是沒有異常發生,忽略 except子句 ,try 子句執行結束
c、若是在執行 try 子句的過程當中發生了異常,那麼 try 子句餘下的部分將被忽略。若是異常的類型和 except 以後的名稱相符,那麼對應的 except 子句將被執行。最後執行 try 語句以後的代碼
d、若是一個異常沒有任何 except 匹配,那麼這個異常將會傳遞給上層的 try中
e、一個 try 語句能包含多個 except 子句,分別來處理不一樣的特定的異常,最多隻有一個分支被執行,處理程序將只針對對應的 try 子句中的異常進行處理,而不是其餘的 try的處理程序中的異常
f、一個 except 子句能夠同時處理多個異常,這些異常將被放在一個括號裏成爲一個元祖,例如
except (RuntimeError, TypeError, NameError):
pass
最後一個 except 子句能夠忽略異常的名稱,它將被看成通配符使用,你可使用這種方法答應你一個錯誤信息,而後在把異常拋出
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
a、使用這個子句,必須放在全部的 except 子句以後,這個子句將在 try 子句沒有發生任何異常的時候執行
b、使用 else子句把全部的語句,都放在try 子句裏面要好,這樣能夠避免一些意想不到的、而 except 又沒有捕獲的異常
import sys
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
else: #必須放在全部 except以後,try子句中沒有發生任何異常的時候執行
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
異常處理並不單單處理哪些直接發生在 try 子句中的異常,並且還能處理子句中調用的函數(甚至間接調用的函數)裏拋出的異常
def this_fails():
x = 1 / 0
try:
this_fails()
except ZeroDivisionError as err: #若是想讓程序繼續運行,可是又由於某種緣由想記錄下錯誤,可使用這種 as xxx,而後在 except中print出來
print('Handling run-time error:', err)
Handling run-time error: int division or modulo by zero
a、Python 使用 raise 語句拋出一個指定的異常
b、raise 惟一的一個參數指定了要拋出的異常,它必須是一個異常的實例或者異常的類(也就是 Exception的子類)
c、若是你只想知道是否拋出一個異常,並不想去處理它,那麼一個簡單的 raise 語句就能夠再次把它拋出
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
a、你能夠經過建立一個新的 exception 來擁有本身的異常,異常應該繼承自 Exception 類,或者直接繼承,或者間接繼承,
b、當建立一個模塊有可能拋出多種不一樣的異常時,一種一般的作法是爲這個包創建一個基礎異常類,而後基於這個基礎類爲不一樣的錯誤狀況建立不一樣的子類
class Error(Exception): #繼承Exception
"""Base class for exceptions in this module."""
pass
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
try 語句中還有另外以一個可選的子句,它定義了不管在任何狀況下都會執行的清理行爲
try:
raise KeyboardInterrupt
finally:
print('Goodbye, world!') #無論有沒有發生異常,finally語句都會被執行
Goodbye, world!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
def divide(x,y):
try:
result = x/y
except ZeroDivisionError: #try發生該類異常則執行該語句,執行完成後在執行 try中異常後的語句
print ("division by zero!")
raise
else: #try中無異常輸出
print ("result is ",result)
finally: #不管如何都會執行
print ("exxecuting finally clause")
divide(2,1)
#輸出
result is 2.0
executing finally clause
divide(2.0)
#輸出
division by zero!
executing finally clause
divide("2","1")
#輸出
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
一些對象定義了標準的清理行爲,不管系統是否成功的使用了它,一旦不須要它了,那麼這個標準的清理行爲就會執行,這面這個例子展現了嘗試打開一個文件,而後把內容打印到屏幕上
for line in open("myfile.txt"):
print(line, end="")
以上這段代碼的問題是,當執行完畢後,文件會保持打開狀態,並無被關閉。
關鍵詞 with 語句就能夠保證諸如文件之類的對象在使用完滯後必定會正確的執行他的清理方法:
with open("myfile.txt") as f:
for line in f:
print(line, end="")
類名 |
描述 |
Exception |
全部異常的基類 |
AttributeError |
特性引用或賦值失敗時引起 |
IOError |
試圖打開不存在文件(包括其餘狀況)時引起 |
IndexError |
在使用序列中不存在的索引時引起 |
KeyError |
在使用映射中不存在的鍵時引起 |
NameError |
在找不到名字(變量)時引起 |
SyntaxError |
在代碼爲錯誤形式時引起 |
TypeError |
在內建操做或者函數應用於錯誤類型的對象時引起 |
ValueError |
在內建操做或者函數應用於正確類型的對象,可是該對象使用不適合的值時引起 |
ZeroDivisionError |
在除法或者模除操做中的第二個參數爲0時引起 |