2012-01-11 40 views
1

Python的教程states:處理異常與else子句

的嘗試... except語句有一個可選的else子句,其中, 存在時,必須遵循所有的除外條款。這對代碼 非常有用,如果try子句不引發異常,則該代碼必須執行。 例如:

for arg in sys.argv[1:]: 
    try: 
     f = open(arg, 'r') 
    except IOError: 
     print 'cannot open', arg 
    else: 
     print arg, 'has', len(f.readlines()), 'lines' 
     f.close() 

使用該else子句是不是增加額外的代碼 到try子句,因爲它避免了意外捕獲異常 不是由代碼募集的被保護更好嘗試...除了 聲明。

問題1>閱讀上述文件後,我仍然沒有得到想法,爲什麼我們不能簡單地將代碼從else子句進入try子句

問題2>如何try子句可能會意外地捕捉異常,因爲所有的捕撈量在做except子句,對不對?

回答

2

回答這兩個問題是相似的,

如果移動代碼在try子句,那麼你就無法從其中異常從哪裏來肯定。因此,如果你有另外一行代碼產生一個意外的IOError,你可以結束搜索一個沒有的問題。

所以爲了更好地檢測你的代碼,你希望儘可能簡化嘗試中儘可能使catch的特性。

6

您可以將else代碼放在try套件中,但是您會發現可能在此處引發的任何異常。如果你不打算這樣做,那將是「偶然的」,因此你鏈接到的文件的措詞。

最佳做法是在try塊中儘可能少地添加代碼,以便發生錯誤時知道哪些操作導致了該錯誤,並且可以正確處理它。如果在try塊中有五行代碼,並且只希望其中一個產生異常,那麼當您預期不會發生異常時,您的異常處理代碼將會準備不足。在這種情況下更好地讓異常被提出,而不是以錯誤的方式處理。

3

如果從其他移動代碼到嘗試那麼它將成爲可引發異常「關鍵路徑」的一部分。如果f.readlines()引發某種異常(由於磁盤上的壞扇區而在讀取文件時可能出現I/O錯誤),那麼該錯誤將與您當前捕獲的一個錯誤混淆。 (從技術上講,「無法打開」的錯誤信息在這一點上是錯誤的......因爲打開一個文件可能會在以後讀取失敗時成功;事實上,在處理它之前,甚至在發生I/O錯誤之前打開它一定會成功) 。

通常你會使用一個模式更像是:

foo = None 
try: 
    # some code to access/load/initialize foo from an external source 
except ...: 
    # handle various types of file open/read, database access, etc errors 
else: 
    foo = something 

...所以你隨後運行的代碼,只需檢查foo是無並使用它或 解決它是不可用的什麼你認爲合適的方式。

1

1)當然,您可以將else子句中的代碼移動到try子句中。您可以將它完全移出try塊,但這樣可以提供額外的靈活性,並進一步調整代碼。另外,也許錯誤被捕獲的特異性。您可以列出可能會發生的不同異常的全部負載,每個異常都有不同的語句。 else子句中的內容仍然只會在try塊中最後一行執行後沒有引發異常時纔會發生。例如打印成功的返回消息。 此外,try子句在垃圾回收管理和錯誤跟蹤方面增加了一些額外的CPU開銷,因此try子句之外的任何內容都沒有以相同方式保護,並且可能運行得更有效。

2)錯誤捕捉是非常具體的。例如以上示例中的except子句只在運行f = open(arg,'r')行時引發IOError時纔會運行。如果您想捕捉任何形式的例外情況,請使用except Exception: