Python中的錯誤處理分爲兩類:語法錯誤和異常處理。語法錯誤一般是指由於python語句、表達式、函數等存在書寫格式活語法規則上的錯誤拋出的異常,如python常見的縮進控制,若同層次的執行語句存在縮進不同,會報語法錯誤(SyntaxError),一般在ide中會有明顯的提示,其屬於編譯階段的錯誤,一般是導致解析錯誤拋出錯誤;異常處理一般是指python語法格式正確,但在運行過程出現錯誤,錯誤類型交由python中的內建異常進行說明,回朔處理,這種類型的處理一般都是出現在運行階段,是需要我們處理的。如下給出兩種錯誤異常的簡單案例.
#語法異常,導致的解析錯誤
str="just show syntax type error."
print str,"\n"
File "exception.py", line 21
print str,"\n"
^
IndentationError: unexpected indent
#內置異常處理
s=None
a=12
print a*s
Traceback (most recent call last):
File "exception.py", line 24, in exceptionDemo
print a*s
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
如上,IndentationError屬於SyntaxError的派生子類,其和TypeError均是派生自Exception而來的,理論上來是Exceptioon可以說是python中所有異常的父類,但只是理論,除了Exception派生的異常內置類外還存在按鍵異常退出,系統異常退出等異常不屬於Exception派生的,根據層次結果,可以確認的是,python中所有異常的父類是BaseException(該類是從python2.5新增的),如下給出內置異常處理類的基本層次結構。
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
| +-- ImportError
| +-- LookupError
| | +-- IndexError
| | +-- KeyError
| +-- MemoryError
| +-- NameError
| | +-- UnboundLocalError
| +-- ReferenceError
| +-- RuntimeError
| | +-- NotImplementedError
| +-- SyntaxError
| | +-- IndentationError
| | +-- TabError
| +-- SystemError
| +-- TypeError
| +-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
而我們常見的自定義異常類一般均是繼承自Exception。如下部分也是主要介紹非系統錯誤,退出導致的異常的處理的相關用法。主要通過如下幾個方面介紹異常處理:
- 異常捕獲
- 異常拋出
- 異常自定義
- 擴展清理操作預定義
異常捕獲
python中如果應爲某些操作(如上的NoneType)導致異常,若是一直未能被捕獲,該異常將一直被傳遞,直至最後終止程序,拋出回朔。我們可以通過在程序中預測異常的發生添加異常的捕獲處理,顯示友好的用戶交互提醒來防止程序的異常結束。python中的異常處理語句以及簡單的使用如下:
try:
'捕獲異常的代碼執行片段'
s = None
a = 12
print a * s
except IOError: #except爲異常發生觸發運行片段關鍵詞,可以指定內置異常類類型,採用匿名類型,不獲取異常信息
print "catch IOError."
except TypeError as error: #捕獲異常定義異常變量,新的API採用'as'來指定變量名稱.
print "catch TypeError.",error
except (UnboundLocalError,BufferError): #捕獲異常定義捕獲的異常類型可以使用元組的形式添加多個捕獲的異常類型.
pass #pass無意義佔位關鍵字
except Exception,error: #捕獲異常Exception,將捕獲所有的繼承自Exception類型的異常,該種定義異常變量的方法屬於老的api,新的api向下兼容.
print "catch Exception and use \',\' define param.",error
except: #捕獲所有的異常類型包括系統異常退出等.
pass
else: #else爲未發生異常執行的代碼塊,必須在except之後
print "no catch any Exception."
finally: #finally不管有沒有出現異常均會執行,可以和try單獨使用,一般用於資源的關閉操作.
針對如上的示例,總結如下異常捕獲的關鍵點:
- 異常捕獲使用格式: try …except….
try:
statement...
except:
statement...
- 異常捕獲可以指定異常捕獲類型,並可以指定異常變量,指定變量有兩種方式,一種通過’,’隔開,一種通過關鍵字’as’指定,格式如下:
#','隔開
try:
statement...
except Exception , error:
pass
#as指定
try:
statement...
except Exception as error:
pass
- 捕獲多種類型的異常可以直接通過元組的方式添加多個異常類型,也可以通過多個except指定,如下:
#元組表示
try:
statement...
except (TypeError,IOError):
statement...
#多個except
try:
statement...
except TypeError:
statement...
except IOError:
statement...
- 使用else代碼塊處理異常未發生的情況,如下:
try:
statement...
except Exception , error:
pass
else:
statement... #沒有發生異常
- 使用finally處理無論是否發生異常捕獲都執行的代碼,可以直接通過和try單獨使用,也可以和except聯合使用(此種情況放在except,else後面)
#和except聯合使用
try:
statement...
except Exception , error:
pass
finally:
statement...
#和try單獨使用
try:
statement...
finally:
statement...
異常拋出
異常拋出可以讓我們定義主動拋出異常的邏輯,以提醒使用者需要進行某些必要的異常判斷或者處理,python中的異常拋出使用關鍵字raise實現,raise的使用方式或者說是基本的使用場景可以分爲三類:
- 匿名拋出
常用拋出,可以直接指定拋出異常類即可,如下:
raise IOError
Traceback (most recent call last):
File "exception.py", line 84, in <module>
raise IOError
IOError
- 實例拋出
實例拋出可以添加異常拋出顯示的提示文本內容,以便幫助定位異常問題,如下:
error=IOError("the file is not exists.")
raise error
Traceback (most recent call last):
File "exception.py", line 85, in <module>
raise error
IOError: the file is not exists.
- 捕獲拋出
這種拋出不常見,但很使用,一般異常拋出關鍵字raise是需要跟一個類或者變量,但這種拋出不要添加任何其他信息,屬於一種異常的傳遞,如下:
a = 12
s = None
try:
print a*s
except Exception as error:
if a < 10:
pass
else:
raise #拋出異常.除了該種情況,raise後面必須要有異常信息(類或者實例)
異常自定義
python中自定義異常一般是繼承Exception或者Exception的子類,可以默認繼承不做處理也可以通過對其進行定製,如下給出兩個示例,一個爲簡單的集成,一個爲重寫方法,如下:
#直接繼承不做處理
class DefException(Exception):
pass
raise DefException("Def Exception")
Traceback (most recent call last):
File "exception.py", line 101, in <module>
raise DefException("Def Exception")
__main__.DefException: Def Exception
#重寫__init__
class CustomerException(Exception):
KEY_CODE="code"
KEY_MESSAGE="message"
def __init__(self,**args):
self.code=args[CustomerException.KEY_CODE]
self.message=args[CustomerException.KEY_MESSAGE]
def __str__(self):
print repr(" throw code:%s,message:%s" % (self.code,self.message))
raise CustomerException(code=21,message="this is customer Exception")
#result
Traceback (most recent call last):
' throw code:21,message:this is customer Exception'
File "/home/hfcai/Projects/PythonProjects/pythonNotes/exercises/basics/exception.py", line 115, in <module>
raise CustomerException(code=21,message="this is customer Exception")
__main__.CustomerException
擴展清理操作預定義
這是python對於文件操作提供的一個自動在操作完成後關閉的操作,使用關鍵字with實現,如下所示:
with open(name="./struct.py",mode="rb+") as file: #這是文件的打開操作.
print file.read() #文件的讀取操作
如上,當執行完with下的代碼塊,file會自動關閉,不論是否發生異常.