錯誤與異常
- AttributeError:嘗試訪問未知的對象屬性
eg.
>>> class myClass(object):
... pass
...
>>> my = myClass()
>>> my.name = 'Yanta'
>>> my.name
'Yanta'
>>> my.age
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'myClass' object has no attribute 'age'
檢測與處理異常
異常通過try語句檢測,任何在try語句塊裏的代碼都會被檢測,檢查有無異常發生
try語句有兩種主要形式:try-except和try-finally. 這兩個語句是互斥的,也就是說你只能使用其中的一種。一個try語句可以對應一個或者多個except語句,但是隻能對應一個finally語句,或者一個try-except-finally複合語句。
也就是說:以下三種形式任選其一。
1、try-except
2、try-finally
3、try-except-finally
其中可以使用try-except語句檢測和處理異常,也可以添加一個可選的else子句處理沒有探測到異常的執行的代碼。
try-finally只允許檢測異常並作一些必要的清除工作(無論發生錯誤與否),沒有任何異常處理措施。
複合語句,兩者都可以做到。
try-except
try-except語句定義了進行異常監控的一段代碼,並且提供了異常處理的機制。
語法形式:
try:
try_suite #監控這裏的異常
except Expection[, reason]:
expect_suite #異常處理代碼
eg.
>>> try:
... os.remove('test01.log')
... except IOError, e:
... print 'Could not remove the file:', e
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
OSError: [Errno 2] No such file or directory: 'test01.log' #異常報錯
處理多個異常的try-except語句:
>>> try:
... os.remove('test01.log')
... except OSError, e:
... print 'No such file or directory: ', e
... except TypeError, e:
... print 'Type argument Error: ', e
...
No such file or directory: [Errno 2] No such file or directory: 'test01.log'
捕獲所有異常
1、有些異常不是由於錯誤條件引起的,比如:SystemExit(當前的python程序需要退出)和KeyboardInterupt(用戶按下了Ctrl+C組合鍵)
2、python2.5之後python異常的繼承發生了變化:
- BaseException
| - KeyboardInterupt
| - SystemExit
| - Exception
| - (all other current built-in exceptions)所有當前內建異常
這樣,當你有一個Exception處理器後,你不必爲這兩個一場創建額外的處理器。
try:
:
except Exception, e:
# handle real errors
如果你確實需要捕捉所有的異常,那麼就需要使用BaseException:
try:
:
except BaseException, e:
# handle real errors
切記
不要再try_suite語段填寫入一大段代碼,再用一個通用的except語句過濾掉任何致命的錯誤,忽略他們。
try-except語句不是用來捕捉過濾所有錯誤然後忽略他們。
異常參數
實際上就是保存引發異常的具體信息,一般爲我們上述書寫的try-except與劇中的e:
>>> try:
... os.remove('test01.log')
... except OSError, e:
... print 'No such file or directory: ', e
... except TypeError, e:
... print 'Type argument Error: ', e
...
No such file or directory: [Errno 2] No such file or directory: 'test01.log'
這個e是OSError異常類的實例,可以調用他的一些屬性來得到詳細信息。也可以調用內置的type()、str()來顯示信息:
>>> type(e)
<type 'exceptions.OSError'>
>>> str(e)
"[Errno 2] No such file or directory: 'test01.log'"
>>> print e
[Errno 2] No such file or directory: 'test01.log'
>>> e
OSError(2, 'No such file or directory')
>>> e.__class__
<type 'exceptions.OSError'>
>>> e.__class__.__doc__
'OS system call failed.'
>>> e.__class__.__name__
'OSError'
else語句
在try-except語句段中,else語句只有在try範圍中沒有異常被檢測到時,纔會被執行。而且在else範圍的任何代碼被運行前,try範圍的所有代碼必須被完全執行成功。不能引發異常。
語句格式:
try:
try_suite
except :
except_suite
else:
else_suite
finally語句
finally語句是無論異常是否發生,是否捕捉都會執行的一段代碼。你也可以將finally語句僅僅和try配合使用,也可以與try-except語句配合使用。
其中try-finally語句是無論異常是否發生,finally代碼段都會被執行。
當try代碼段引發一個異常時,會馬上跳轉到finally語句段,然後當finally代碼段被執行完畢後會繼續向上一層引發異常:
>>> try:
... os.remove('test01.log')
... finally:
... print '無論如何這裏都會被執行!'
...
無論如何這裏都會被執行!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
OSError: [Errno 2] No such file or directory: 'test01.log'
切記
若果finally代碼段引發了另一個異常或者由於return、break、continue語法而終止,原來的異常將丟失而且無法重新引發。
>>> try:
... os.remove('test01.log')
... finally:
... os.rmdir('test')
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
OSError: [Errno 2] No such file or directory: 'test'
>>>
上下文管理
with語句是用來簡化代碼的,這與用try-except和try-finally福哦想達到的目的前後呼應。try-except和try-finally的一種特定的配合用法是保證共享的資源的唯一分配,並在任務結束時候釋放它。比如文件(數據、日誌、數據庫等)、線程資源、簡單同步、數據庫連接,等等。with語句的目的就是應用在這種場景。
然而,with語句的目的在於從流程圖中巴try、except和fianlly關鍵字和資源分配釋放相關代碼統統去掉,而不是像try-except-finally那樣僅僅簡化代碼爲之所用。
基本語法如下:
with context_expr [as var]:
with_suite
with語句涉及到一些內在的處理細節。with語句僅僅支持上下文管理協議的對象,只有內建了“上下文管理”的對象可以和with一起工作。目前支持該協議的對象有:
* file
* decimal.Context
* thread.LockType
* thread.Lock
* thread.RLock
* thread.Condition
* thread.Semaphore
* thread.BoundedSemaphore
一打開文件爲例,with語句會完成準備工作,當完成操作後,會關閉文件。而且無論在這段代碼的開始、中間和結尾是發生日常,都會執行清理的代碼,此外文件仍會自動關閉。eg.
>>> with open('test.log', 'r') as f0:
... for eachline in f0:
... print eachline
...
121
weqefse
1rfewf
1rfegvd
1rfvfdfsv cb
fsdvfvc
現在我們來測試f0:
>>> f0
<closed file 'test.log', mode 'r' at 0x7fbe66a25300>
>>> type(f0)
<type 'file'>
>>> f0.closed #文件是否被關閉
True
>>> f0.name
'test.log'
>>> f0.mode
'r'
與正常代開文件做對比:
>>> ff = open('test.log', 'r')
>>> type(ff)
<type 'file'>
>>> ff.closed #文件是否被關閉
False
>>> ff.name
'test.log'
>>> ff.mode
'r'
>>> ff.close()
>>> ff
<closed file 'test.log', mode 'r' at 0x7fbe66a25420>
>>> type(ff)
<type 'file'>
>>> ff.name
'test.log'
>>> ff.mode
'r'
>>> ff.closed #文件是否被關閉
True
觸發異常
Python提供一種機制讓程序員明確的觸發異常,這就是raise語句。
raise語句的一般用法:
raise [SomeException [, args [, traceback]]]
raise語句的用法列表:
斷言
斷言是一套必須等價於布爾真的判定;此外發生異常也就意味着表達式爲假。
斷言通過assert語句來實現,測試一個表達式,如果返回值爲假,則觸發異常。
assert語句語法格式:
assert expression [, arguments]
示例:
>>> assert 1 == 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
>>> try:
... assert 1 == 0
... except AssertionError, e:
... e
...
AssertionError()
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 #縮進錯誤
IndentationError #縮進錯誤
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 #用戶代碼生成的警告
異常與sys模塊
另一種獲取異常信息的途徑是通過sys模塊的exc_info()函數,其提供一個三元組的信息。
>>> try:
... float('ada1313')
... except:
... import sys
... exc_tuple = sys.exc_info()
...
>>> print exc_tuple
(<type 'exceptions.ValueError'>, ValueError('could not convert string to float: ada1313',), <traceback object at 0x7fa699bfc908>)
這個三元組中包含着三個信息:
1、異常類
2、異常類的實例
3、跟蹤記錄對象